ICallHandler是一个接口,不能被构造

本文关键字:不能 接口 一个 ICallHandler | 更新日期: 2023-09-27 18:04:22

在下面的代码中,我得到了错误: 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();

输出……

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

然而,我希望应用策略规则。如果应用了策略规则,则输出应该类似于我不使用Intercept.ThroughProxy<>方法

下面代码的不同输出,我使用容器来解析对象,而不是通过Intercept.ThroughProxy<>方法来解析对象。

 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>

ICallHandler是一个接口,不能被构造

我不能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 AM调用Sleep
蚊子睡觉…
蚊子吸……

显示Sleep被拦截,因为这是我们调用的唯一的方法,我们为其设置了匹配规则。

另外,我使用编程配置,我必须添加一个默认构造函数到LoggingCallHandler,并告诉Unity使用该构造函数(因为Unity不知道如何在没有注册的情况下解析NameValueCollection)。