LightInject PerWebRequest Interception



这是特定于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

相关内容

  • 没有找到相关文章

最新更新