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>
我不能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)。