开发者

Ninject Failing Silently

开发者 https://www.devze.com 2023-03-18 21:50 出处:网络
I am evaluating Ninject for a project, and the only issue I have had with it is that it fails silently on property injection.If I call

I am evaluating Ninject for a project, and the only issue I have had with it is that it fails silently on property injection. If I call

Kernel.Get<ISomething>();

on a faulty binding, it will fail with an exception, but if I use property injection:

[Inject]
public ISomething Something { get; set;}

it fails silently. I don't know there's an issue until I go to use t开发者_C百科he reference and it is null. Any ideas on how to make this fail with an exception?


This is simply not correct. Although constructor injection is preferred (as Remo comments), if Ninject sees an [Inject] property attribute and doesn't have a binding, it will throw an ActivationException.

Here's an example.

Dependency:

public interface IHello
{
    void SayHello();
}

public class Hello : IHello
{
    public void SayHello()
    {
        Console.WriteLine("Hello world!");
    }
}

Dependent class:

public class MyApp : IApp
{
    public virtual void Run()
    {
        Hello.SayHello();
    }

    [Inject]
    public IHello Hello { get; set; }
}

Main Program:

class Program
{
    static void Main(string[] args)
    {
        var kernel = new StandardKernel();
        kernel.Bind<MyApp>().ToSelf();
        //kernel.Bind<IHello>().To<Hello>();
        var app = kernel.Get<MyApp>();
        app.Run();
    }
}

If you run this, you will get the following exception:

Error activating IHello  
No matching bindings are available, and the type is not self-bindable.  
Activation path:  
  2) Injection of dependency IHello into property Hello of type MyApp  
  1) Request for MyApp  

Uncomment the kernel.Bind<IHello>().To<Hello>() line above and it will run correctly.

As Ruben comments, Ninject will only "fail silently" if you also add [Optional] to the [Inject]-ed property. Which is because you've now told Ninject that a missing binding is not a failure, but an expected condition. Otherwise, property injection works exactly the same as constructor injection.


I suspect that you may be making a common mistake for people who are new to dependency injection: instantiating a dependent class (with an [Inject]ed property) with new and assuming that the injection "just happens". It doesn't work that way.

In order for Ninject or any other DI library to work its magic, you must instantiate the container with the binding root - in other words, whichever class contains the Something property must itself be created using kernel.Get<ClassContainingSomething>().

0

精彩评论

暂无评论...
验证码 换一张
取 消