0

这是特定于 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 逻辑,然后决定在那里使用或绕过拦截逻辑,但我想避免在禁用跟踪时创建代理,以避免通过反射产生代理调用的开销,但这只有在 Intercept 时才有可能为每个 Web 请求调用方法。请让我知道它是否可行或有更好的方法?

谢谢,

赛义德丹麦人。

4

1 回答 1

3

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

此致

伯恩哈德·里希特

于 2014-07-31T17:24:56.693 回答