Question

TL;DR: Kernel.Get<T> works when called from a .net/WPF app, but blows up with an inner ActivationException (inside a TargetInvocationException) when called from a VB6 app. WTH?

This is a bit of a follow-up on this question where I configured an abstract factory with Ninject conventions, in such a way that I never need to actually implement one, the Ninject factory extension takes care of generating one on-the-fly.

This worked beautifully... until I needed to run my library from VB6 code.

_kernel.Bind(t => t.FromAssemblyContaining(typeof(ViewModelBase))
       .SelectAllInterfaces()
       .EndingWith("ViewFactory")
       .BindToFactory());

As soon as I call anything on the app from VB6 code, if I wrap the resolving of dependencies inside a try/catch block, I'm trapping a TargetInvocationException with an inner ActivationException:

Error activating IInterceptor using conditional implicit self-binding of IInterceptor Provider returned null. Activation path:

3) Injection of dependency IInterceptor into parameter of constructor of type IViewFactoryProxy

2) Injection of dependency IViewFactory into parameter viewFactory of constructor of type MsgBox

1) Request for IMsgBox

Suggestions:

1) Ensure that the provider handles creation requests properly.

I have no reference to the Ninject.Interception extension (at this point).

Oddly if instead of launching VB6 I launch a sandbox WPF test app when I debug, I don't get any ActivationException and everything works like a charm.

The VB6 code dies with automation error -2146232828 (80131604) which yields nothing on Google, but I'm guessing it has to do with the TargetInvocationException being thrown.

As far as .net code is concerned it just works: if I compose the app from a WPF client I can break in the MsgBox class constructor and see that the IViewFactory parameter is happy with a Castle.Proxy.IViewFactoryProxy; if I compose the app from a VB6 ActiveX DLL (I also created a VB6 EXE to test and same as the DLL), it blows up.

UPDATE

I removed the generic abstract factories, and I no longer get this error. And because I don't want to be writing factories, I went for a bit of tighter coupling that I can live with. Now I'd like to know why this was happening!

Was it helpful?

Solution

I ran into this exception today in a completely different context to you. I was trying to use a kernel configured with a custom module inside a design time view model in the VS WPF Designer. The module had a number of interfaces configured using the ToFactory() extension method.

The problem was that for some reason the Ninject.Extensions.Factory.FuncModule was not loaded automatically when I was initialising my kernel, possibly due to some trickery in the way the VS designer handles creating design time classes (maybe it didn't load the appropriate assembly or something, who knows).

I had a unit test that was creating one of these design time view models, and it worked perfectly, so it was definitely something related to the designer.

I fixed the issue by creating a special kernel for my design time view models.

public class DT_Kernel : StandardKernel
{
    public DT_Kernel()
        : base(new MyModule())
    {
        if (!HasModule(typeof(FuncModule).FullName)) 
        {
            Load(new[] { new FuncModule() });
        }
    }
}

The important part of this code is the bit that loads the FuncModule if it isn't already loaded.

You might be able to leverage that code to fix your issue.

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