seesharper / LightInject.Interception

LightInject.Interception supports Aspect Oriented Programming through proxy-based method interceptors.
11 stars 7 forks source link

Interceptor not called unless called by resolving from the container #37

Open acrigney opened 1 year ago

acrigney commented 1 year ago

Guys love LightInject its sooo much faster than other DI containers! But I am unable to get the interceptor to work unless I resolve the object from the container, I would have thought that once the interception is setup as long as you use the same object it should work? Unable to determine the implementing type. Here is a little test app. TestAOP.zip

seesharper commented 1 year ago

Try this

internal class Program
    {
        static void Main(string[] args)
        {

            var container = new LightInject.ServiceContainer();
            var t = new Tester();
            container.Register<Tester>();

            container.Intercept(sr => true, (sf, pd) => DefineProxyType(pd));

            //t.DoTest(); // the interceptor is not called

            var r = container.GetInstance<Tester>().DoTest(); // Crashes with Unable to determine the implementing type.
        }

        private static void DefineProxyType(ProxyDefinition proxyDefinition)
        {
            proxyDefinition.Implement(() => new AuditInterceptor(), m => m.Name.Contains("DoTest"));
        }
    }

Also intercepted methods needs to be virtual

public class AuditInterceptor : IInterceptor {
        public object Invoke(IInvocationInfo invocationInfo) {
            // Perform logic before invoking the target method
            var returnValue = invocationInfo.Proceed();

            // Perform logic after invoking the target method
            return returnValue;
        }
    }
acrigney commented 1 year ago

Sorry mate I made DoTest virtual but no luck. But would //t.DoTest(); work? With Castle Windsor you need to reference the instance from the container. Maybe you can post back your code?

acrigney commented 1 year ago

Looks like the only way is using an interface.

var container = new LightInject.ServiceContainer();

        container.Register<ITester, Tester>();
        container.Intercept(sr => sr.ServiceType == typeof(ITester), sf => new AuditInterceptor());

        var instance = container.GetInstance<ITester>();

        var x = instance.DoTest(); // works

        container.Register<Tester>();
        container.Intercept(sr => true, sf => new AuditInterceptor());
        container.Intercept(sr => sr.ServiceType == typeof(Tester), sf => new AuditInterceptor());

        var xx = container.GetInstance<Tester>();

        var y = xx.DoTest(); // doesn't work
seesharper commented 1 year ago

It has to be either an interface or a class with virtual members 👍

acrigney commented 1 year ago

Mate I got it to work just using types without interfaces in my code!