在下面的代码中我得到错误: 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>
答案 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)。如果使用配置,则可能没有此问题。