这是特定于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方法一次,并且对于所有后续请求,它都重用相同的Intercept机制。
我也知道我可以在MyServiceInterceptor中使用ITraceSwitcher逻辑,然后决定在那里使用或绕过拦截逻辑,但我想避免创建代理开始,如果跟踪被禁用,以避免通过反射代理调用的开销,但这只有在拦截方法被调用时才有可能。请让我知道这是可行的还是有更好的方法?
谢谢,
Syed丹麦人。
您可以将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 { }
敬上
Bernhard Richter