LightInject PerWebRequest拦截

时间:2014-07-31 15:49:09

标签: dependency-injection aop interception perwebrequest light-inject

这特定于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方法一次,并且对于所有后续请求,它重用相同的拦截机制。

我也知道我可以在MyServiceInterceptor中使用ITraceSwitcher逻辑,然后决定在那里使用或绕过拦截逻辑但我想避免创建代理,如果禁用跟踪以避免代理调用通过反射开销,但这只是如果为每个Web请求调用Intercept方法,则可能。请告诉我它是否可行或有更好的方法?

谢谢,

Syed Danish。

1 个答案:

答案 0 :(得分:2)

您可以将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