Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to cast exception on Injection with Dynamic Proxy and Interface Inheritance #45

Open
spam1923 opened this issue Jan 24, 2018 · 0 comments

Comments

@spam1923
Copy link

I have ran into an issue when binding two interfaces to the same concrete class when there is an Interceptor on the singleton binding.
Without the Interceptor these tests will all pass because when InterfaceA or InterfaceB is injected it is injected as the concrete class type. However with the interceptors it puts Castle.Proxies.InterfaceAProxy Or Castle.Proxies.InterfaceBProxy purely dependent upon which Kernel.Get was called first. Since InterfaceA inherits from InterfaceB, when InterfaceA goes first it can cast as the proxy for InterfaceB. But it will not work the other way around.

I have taken the complexity out of the instance I ran into and put it into a very basic scenario below. To run this snippet create a UnitTest Project in VisualStudio and add the Ninject.Extensions.Interception.DynamicProxy NuGet Package v3.3.3.

    public class Interceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            //Interceptor Logic
        }
    }

    public interface InterfaceB
    {
        //Definition
    }
    public interface InterfaceA : InterfaceB
    {
        //Definition
    }
    public class Implementation : InterfaceA
    {
        //Logic
    }

    public class BusinessLogic_One
    {
        private readonly InterfaceA _interface;
        public BusinessLogic_One(InterfaceA input)
        {
            _interface = input;
        }
    }

    public class BusinessLogic_Two
    {
        private readonly InterfaceB _interface;
        public BusinessLogic_Two(InterfaceB input)
        {
            _interface = input;
        }
    }

    [TestClass]
    public class UnitTests
    {
        private IKernel _kernel;
        [TestInitialize]
        public void TestInit()
        {
            _kernel = new StandardKernel();

           //If the Intercept().With<Interceptor>() is commented out all tests will pass.
            _kernel.Bind<InterfaceA, InterfaceB>().To<Implementation>().InSingletonScope()
                .Intercept().With<Interceptor>();
            _kernel.Bind<BusinessLogic_One>().ToSelf().InSingletonScope();
            _kernel.Bind<BusinessLogic_Two>().ToSelf().InSingletonScope();
        }

         
        [TestMethod]//Test Passes
        public void Test_Calling_KernelGet_InterfaceAFirst()
        {
            var bl1 = _kernel.Get<BusinessLogic_One>();//InterfaceA
            var bl2 = _kernel.Get<BusinessLogic_Two>();//InterfaceB
        }

        [TestMethod]//Test Fails
        public void Test_Calling_KernelGet_InterfaceBFirst()
        {
            var bl2 = _kernel.Get<BusinessLogic_Two>();//InterfaceB
            var bl1 = _kernel.Get<BusinessLogic_One>();//InterfaceA
        }
    }

The Exception I get on the Failed test is:
Message: Test method UnitTests.Test_Calling_KernelGet_InterfaceBFirst threw exception:
System.InvalidCastException: Unable to cast object of type 'Castle.Proxies.InterfaceBProxy' to type 'InterfaceA'.

Would it be possible in the next version for this to be a Castle.Proxies.ImplementationProxy or something that both interfaces could inherit from?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant