Question

This is specific to LightInject's interception. Is it possible to apply interception logic based on PerWebRequest lifetime so that interception logic can be conditionally turned on/off based on user input? E.g. something like this.

    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();
    }

Now because IMyService lifetime is defined as PerWebRequest so it is created for every web request and I was under impression that it would also call Intercept method everytime it creates MyService instance so that it can dynamically decide to apply interception logic depending on whether tracing is enabled or disabled by user. However it looks like that it calls Intercept method only once for the first time when IMyService instance is requested and for all subsequent requests it reuses the same Interception mechanism.

I also know I can use ITraceSwitcher logic within MyServiceInterceptor and then decide to use or bypass interception logic there but I want to avoid creation of proxies to begin with if tracing is disabled to avoid overhead of proxy calls through reflection but this is only possible if Intercept method is called for every web request. Please let me know if it's doable or there is a better way?

Thanks,

Syed Danish.

Was it helpful?

Solution

You can put the IsTracingEnabled method call directly into the predicate that decides if the services should be intercepted. The proxy type will only be created if it matches the predicate.

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 { }

Best regards

Bernhard Richter

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top