What exactly are the steps to auto inject Func<T>?

145 views Asked by At

I'm trying to set up a service class where I would like to inject a simple Func<OtherService> factory method in its constructor. Type OtherService is a class, which should be self-bound (and is indeed when I inject it without factory).

I've installed the latest Ninject core, and Ninject.Extensions.Factory NuGet packages. When I try to retrieve an instance from Ninject, I get an activation exception about not being able to activate IntPtr.

What am I doing wrong? If I understand correctly the documentation of the Factory extension, this type of Func binding should be automatic, without any configuration. Do I need to register the Factory extension anywhere, or create an explicit binding for OtherService? Any tips would be appreciated.

EDIT:

I have Ninject and Ninject.Extensions.Factory installed in a small separate project, where I do some customizations on Ninject. These are the following:

Kernel.Components.Add<IInjectionHeuristic, CustomInjectionHeuristic>();
Kernel.Components.Add<IActivationStrategy, TransientDisposableActivationStrategy>();

where the two custom handlers are for letting me use my custom [Service] attribute for indicating property injection, and for handling disposing of components which use my own IDisposableEx interface (with Disposed notification) for Ninject cache fine tuning.

public class CustomInjectionHeuristic : NinjectComponent, IInjectionHeuristic, INinjectComponent, IDisposable
{
    public bool ShouldInject(MemberInfo member)
    {
        return member.IsDefined(typeof(ServiceAttribute), true);
    }
}

public class TransientDisposableActivationStrategy : ActivationStrategy
{
    public override void Activate(IContext context, InstanceReference reference)
    {
        var scope = context.GetScope();
        // care about only transient scoped objects
        if (scope != null) return;
        if (reference.Instance is Component)
            reference.Instance.As<Component>().Disposed +=
                (sender, args) => context.Kernel.Components.Get<ICache>().Clear(sender);
        if (reference.Instance is IDisposableEx)
            reference.Instance.As<IDisposableEx>().Disposed +=
                (sender, args) => context.Kernel.Components.Get<ICache>().Clear(sender);
    }
}

And I also use the Ninject.Extensions.NamedScope extension for InCallScope() bindings.

Any of these customizations could have effect on proper work of the factory?

EDIT2:

I think I got it. The problem seems to be that I have to reference the Factory extension in my startup project, where I define bindings, and not in the class library where I have my basic Ninject setup. So the key is that I have to reference any binding-related extension in that project where I define the bindings. Anyway, sounds logical...

1

There are 1 answers

0
Zoltán Tamási On BEST ANSWER

The problem seems to be that I have to reference the Factory extension in my startup project, where I define bindings, and not in the class library where I have my basic Ninject setup. So the key is that I have to reference any binding-related extension in that project where I define the bindings. Anyway, sounds logical...