ICallHandler是一个接口,无法构造

时间:2015-07-24 10:59:37

标签: c# dependency-injection enterprise-library

在下面的代码中我得到错误 ICallHandler,是一个接口,在解析对象时无法构造

            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作为下面的代码,它运行

    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();

... outputing

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

但是,我希望应用策略规则。如果应用了策略规则,则ouptut应该就像我不会使用Intercept.ThroughProxy&lt;&gt;方法

查看以下代码的不同输出,我使用容器来解析对象而不是通过Intercept.ThroughProxy&lt;&gt;来解析对象方法..

 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>

1 个答案:

答案 0 :(得分:1)

由于未显示容器注册码而且我不确定配置代码的来源,我不能100%确定您的具体情况。

然而,看起来问题在于如何注册呼叫处理程序。调用处理程序的名称(不是类名)是传递给RuleDrivenPolicy的内容。您正在传入“LoggingCallHandler”,但容器的注册是“LoggingCallHandler-LoggingFlyGoreJumpSleepMethodPolicy”。

如果您对齐命名,那么它应该有效。

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调用睡眠
  蚊子睡觉...
  蚊子吮吸......

显示睡眠被截获,因为这是我们调用的唯一方法,我们已经设置了匹配规则。

另外,我使用的是程序化配置,我不得不向LoggingCallHandler添加一个默认构造函数,并告诉Unity使用该构造函数(因为Unity不知道如何在没有注册的情况下解析NameValueCollection)。如果使用配置,则可能没有此问题。