这是专门针对LightInject的拦截。能否应用基于PerWebRequest生命期的拦截逻辑,以便根据用户输入有条件地打开/关闭侦听逻辑?像这样的事情。
public static void Configure()
{
var serviceContainer = new ServiceContainer();
serviceContainer.EnablePerWebRequestScope();
serviceContainer.Register<ITraceSwitcher, TraceSwitcher>(new PerScopeLifetime());
serviceContainer.Register<IMyService, MyService>(new PerScopeLifetime());
serviceContainer.Intercept(x => x.ServiceType == typeof(IMyService), (y, z) => DefineProxyType(z, IsTracingEnabled));
ServiceLocator.SetLocatorProvider(() => new LightInjectServiceLocator(serviceContainer));
}
private static void DefineProxyType(ProxyDefinition proxyDefinition, Func<bool> isTracingEnabled)
{
if (isTracingEnabled())
proxyDefinition.Implement(() => new MyServiceInterceptor(), m => m.Name == "SomeMethod");
}
private static bool IsTracingEnabled()
{
var traceSwitcher = ServiceLocator.Current.GetInstance<ITraceSwitcher>();
return traceSwitcher.IsTracingEnabled();
}现在,由于IMyService生存期被定义为PerWebRequest,因此它是为每个web请求创建的,因此我的印象是,每次创建MyService实例时,它也会调用Intercept方法,以便根据用户是否启用或禁用跟踪,动态决定应用拦截逻辑。但是,当请求IMyService实例时,它似乎只第一次调用了Intercept方法一次,而对于所有后续请求,它都重用了相同的拦截机制。
我还知道我可以在ITraceSwitcher内部使用MyServiceInterceptor逻辑,然后决定在那里使用或绕过拦截逻辑,但我希望首先避免创建代理,如果禁用了跟踪,以避免通过反射调用代理调用的开销,但这只有在每个web请求都调用Intercept方法时才有可能。请告诉我这是可行的还是有更好的方法?
谢谢,
赛德·丹麦尔。
发布于 2014-07-31 17:24:56
您可以将IsTracingEnabled方法调用直接放入谓词中,以决定是否应该拦截服务。只有当代理类型与谓词匹配时,才会创建代理类型。
using LightInject;
using LightInject.Interception;
class Program
{
static void Main(string[] args)
{
var container = new ServiceContainer();
container.Register<IFoo, Foo>();
container.Intercept(sr => sr.ServiceType == typeof(IFoo) && IsTracingEnabled(), (factory, definition) => DefineProxyType(definition));
var foo = container.GetInstance<IFoo>();
}
private static void DefineProxyType(ProxyDefinition proxyDefinition)
{
proxyDefinition.Implement(() => new SampleInterceptor(), m => m.Name == "SomeMethod");
}
private static bool IsTracingEnabled()
{
return true;
}
}
public class SampleInterceptor : IInterceptor
{
public object Invoke(IInvocationInfo invocationInfo)
{
return invocationInfo.Proceed();
}
}
public interface IFoo { }
public class Foo : IFoo { }诚挚的问候
伯恩哈德里克特
https://stackoverflow.com/questions/25063473
复制相似问题