ICallHandler,是一个接口,无法构造 [英] ICallHandler, is an interface and cannot be constructed

查看:72
本文介绍了ICallHandler,是一个接口,无法构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,我遇到了错误: ICallHandler,它是一个接口,在解决对象时无法构造

At code below I got the error: ICallHandler, is an interface and cannot be constructed when resolving the object

            var attributePolicy = new AttributeDrivenPolicy();
            var rulePolicy = new RuleDrivenPolicy("LoggingFlyGoreJumpSleepMethodPolicy", new IMatchingRule[] { new MemberNameMatchingRule(new string[] { "Fly", "Gore", "Jump", "Sleep" }), new AssemblyMatchingRule("Domain") }, new string[] { "LoggingCallHandler", "CounterCallHandler" });
            var interceptor = new InterfaceInterceptor();
            var policies = new InjectionPolicy[] { attributePolicy, rulePolicy };
            var request = new CurrentInterceptionRequest(interceptor, typeof(IMosquito), mosquito.GetType());
            var behaviour = new PolicyInjectionBehavior(request, policies, _container); // *(1) we need a container just to resolve the LoggingCallHandler and CounterCallHandler
            var proxyMosquito = Intercept.ThroughProxy<IMosquito>(mosquito, interceptor, new IInterceptionBehavior[] { behaviour });
            proxyMosquito.Eat();
            proxyMosquito.Sleep();
            proxyMosquito.Suck();

我无法使用RuleDrivenPolicy 但是如果我将RuleDrivenPolicy删除为下面的代码,它将运行

I can't get working the RuleDrivenPolicy but if I remove the RuleDrivenPolicy as code below, it runs

    var attributePolicy = new AttributeDrivenPolicy();
    var interceptor = new InterfaceInterceptor();
    var policies = new InjectionPolicy[] { attributePolicy };
    var request = new CurrentInterceptionRequest(interceptor, typeof(IMosquito), mosquito.GetType());
    var behaviour = new PolicyInjectionBehavior(request, policies, null); // *(2) container removed
    var proxyMosquito = Intercept.ThroughProxy<IMosquito>(mosquito, interceptor, new IInterceptionBehavior[] { behaviour });
    proxyMosquito.Eat();
    proxyMosquito.Sleep();
    proxyMosquito.Suck();

输出...

Mosquito Eating...
Mosquito Sleeping...
LoggingCallHandler Invoking Suck at 12:36:29
Mosquito Sucking...

但是,我希望应用该策略规则.如果应用了策略规则,则输出应该就像我不会使用Intercept.ThroughProxy<>方法

However, I want the policy rule to be applied. If the policy rule is applied, the ouptut should be like as if I won't be using the Intercept.ThroughProxy<> method

查看以下代码的不同输出,在这里我使用容器来解析对象,而不是通过Intercept.ThroughProxy<>方法来解析对象.

Look the different output of code below, where I use the container to resolve the object instead of getting the object resolved through Intercept.ThroughProxy<> method..

 var proxyMosquito = _container.Resolve<IMosquito>();
    proxyMosquito.Eat();
    proxyMosquito.Sleep();
    proxyMosquito.Suck();

然后输出..

Mosquito Eating...
LoggingCallHandler Invoking Sleep at 12:43:07
Mosquito Sleeping...
LoggingCallHandler Invoking Suck at 12:43:08
Mosquito Sucking...

该容器具有以下注册.

+ IUnityContainer '[default]' Container
+ IMatchingRule -> MemberNameMatchingRule 'Member Name Matching Rule-LoggingFlyGoreJumpSleepMethodPolicy' Transient
+ IMatchingRule -> AssemblyMatchingRule 'Assembly Matching Rule-LoggingFlyGoreJumpSleepMethodPolicy' Transient
+ ICallHandler -> LoggingCallHandler 'LoggingCallHandler-LoggingFlyGoreJumpSleepMethodPolicy' ContainerControlled
+ ICallHandler -> CounterCallHandler 'CounterCallHandler-LoggingFlyGoreJumpSleepMethodPolicy' ContainerControlled
+ InjectionPolicy -> RuleDrivenPolicy 'LoggingFlyGoreJumpSleepMethodPolicy' Transient
+ InjectionPolicy 'Microsoft.Practices.Unity.InterceptionExtension.AttributeDrivenPolicy, Microsoft.Practices.Unity.Interception, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ContainerControlled
+ IServiceLocator '[default]' ExternallyControlled
+ IMosquito -> Mosquito '[default]' Transient
+ ExceptionManager '[default]' Transient
+ Database '[default]' Transient
+ ValidatorFactory '[default]' ContainerControlled

以下是实施的基础知识

 public class Mosquito : IMosquito
    {

        public void Bit()
        {
            Console.WriteLine("Mosquito Biting...");
        }

        public void Eat()
        {
            Console.WriteLine("Mosquito Eating...");
        }

        public void Sleep()
        {
            Console.WriteLine("Mosquito Sleeping...");
        }

        [LoggingCallHandler(1)]
        public void Suck()
        {
            Console.WriteLine("Mosquito Sucking...");
        }
    }

    public interface IMosquito : IAnimal
    {
        void Suck();
    }

    public interface IAnimal
    {
        void Eat();
        void Sleep();
    }

    [ConfigurationElementType(typeof(CustomCallHandlerData))]
    public class LoggingCallHandler : ICallHandler
    {
        public LoggingCallHandler(NameValueCollection attributes)
        {

        }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            if (getNext == null) throw new ArgumentNullException("getNext");

            Console.WriteLine("LoggingCallHandler Invoking {0} at {1}", input.MethodBase.Name, DateTime.Now.ToLongTimeString());
            return getNext()(input, getNext);
        }

        public IEnumerable<Type> GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

        public int Order { get; set; }
    }

    public class LoggingCallHandlerAttribute : HandlerAttribute
    {
        private readonly int _order;

        public LoggingCallHandlerAttribute(int order)
        {
            _order = order;
        }

        public override ICallHandler CreateHandler(IUnityContainer container)
        {
            return new LoggingCallHandler(new NameValueCollection()) { Order = _order };
        }
    }

 <?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
  <container>
    <extension type="Interception" />
    <register type="Domain.IMosquito, Domain" mapTo="Domain.Mosquito, Domain">
      <interceptor type="InterfaceInterceptor" />
      <policyInjection />
    </register>
  </container>
</unity>


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection" requirePermission="true" />
  </configSections>
  <policyInjection>
    <policies>
      <add name ="LoggingFlyGoreJumpSleepMethodPolicy">
        <matchingRules>
          <add name="Member Name Matching Rule" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection">
            <matches>
              <add match="Fly" />
              <add match="Gore" />
              <add match="Jump" />
              <add match="Sleep" />
            </matches>
          </add>
          <add name="Assembly Matching Rule" match="Domain" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.AssemblyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection"/>
        </matchingRules>
        <handlers>
          <add name="LoggingCallHandler" order="1" type="IoCnAOP.LoggingCallHandler, IoCnAOP" />
        </handlers>
      </add>
    </policies>
  </policyInjection>
</configuration>

推荐答案

由于未显示容器注册代码,而且不确定配置代码在哪里,因此我不确定100%确定您的确切情况.

I'm not 100% sure what your exact situation is since the container registration code is not shown and I'm not sure where the configuration code comes in.

但是,问题似乎在于如何注册呼叫处理程序.呼叫处理程序的名称(不是类名称)是传递给RuleDrivenPolicy的内容.您正在传递"LoggingCallHandler",但是该容器的注册是针对"LoggingCallHandler-LoggingFlyGoreJumpSleepMethodPolicy"的.

However, it looks like the issue is in how the call handlers are registered. The name of the call handler (not the class name) is what is passed in to the RuleDrivenPolicy. You are passing in "LoggingCallHandler" but the container's registration is for "LoggingCallHandler-LoggingFlyGoreJumpSleepMethodPolicy".

如果您对齐命名,那么它应该起作用.

If you align the naming then it should work.

var interceptor = new InterfaceInterceptor();

var rulePolicy = new RuleDrivenPolicy("LoggingFlyGoreJumpSleepMethodPolicy",
    new IMatchingRule[] { new MemberNameMatchingRule(new string[] { "Fly", "Gore", "Jump", "Sleep" }) },
    new string[] { "LoggingCallHandler-LoggingFlyGoreJumpSleepMethodPolicy" });

var policies = new InjectionPolicy[] { rulePolicy };
var request = new CurrentInterceptionRequest(interceptor, typeof(IMosquito), mosquito.GetType());
var behaviour = new PolicyInjectionBehavior(request, policies, container); 
var proxyMosquito = Intercept.ThroughProxy<IMosquito>(mosquito, interceptor, new IInterceptionBehavior[] { behaviour });
proxyMosquito.Eat();
proxyMosquito.Sleep();
proxyMosquito.Suck();

这将显示:

吃蚊子...
LoggingCallHandler调用上午11:39:35的睡眠
蚊子睡觉...
蚊子吸...

Mosquito Eating...
LoggingCallHandler Invoking Sleep at 11:39:35 AM
Mosquito Sleeping...
Mosquito Sucking...

显示睡眠已被拦截,因为这是我们称为唯一为其设置匹配规则的方法.

Showing that Sleep was intercepted since that was the only method we called that we had set a matching rule for.

此外,我正在使用编程配置,我必须向LoggingCallHandler添加默认构造函数,并告诉Unity使用该构造函数(因为Unity不知道如何在不注册的情况下解析NameValueCollection).如果使用配置,则可能没有该问题.

Also, I was using programmatic configuration and I had to add a default constructor to LoggingCallHandler and tell Unity to use that constructor (since Unity does not know how to resolve NameValueCollection without a registration). You might not have that issue if using configuration.

这篇关于ICallHandler,是一个接口,无法构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆