Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject Property Injection on base class

I'm attempting to inject a property using ninject. Given the two bindings in the ninject module below, I would expect the ConcreteDependency to be injected into B.
However, it seems that WhenInjectedInto doesn't consider the type being injected into, just the declaring type of the target (property in this case).

Is there a way to achieve the behaviour I expected?

static void Main(string[] args)
{
    var kernel = new StandardKernel(new TestModule());
    var b = kernel.Get<B>();
    var c = kernel.Get<C>();
}

class TestModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDependency>().To<EmptyDependency>();
        Bind<IDependency>().To<ConcreteDependency>().WhenInjectedInto<B>();
    }
}

abstract class A
{
    [Inject]
    public IDependency Dependency { get; set; }
}

class B : A {}

class C : A {}

interface IDependency {}

class EmptyDependency : IDependency { }

class ConcreteDependency : IDependency { }
like image 488
Gibsnag Avatar asked Nov 03 '12 22:11

Gibsnag


People also ask

What is ninject dependency injection?

NInject is a popular IOC container that can be used to inject dependencies in your WebAPI controllers easily. IDG. Dependency injection is a software design pattern that helps you to build pluggable implementations in your application using loosely coupled, testable components.

What are the three types of dependency injection?

There are three main styles of dependency injection, according to Fowler: Constructor Injection (also known as Type 3), Setter Injection (also known as Type 2), and Interface Injection (also known as Type 1).

How are dependencies injected?

In software engineering, dependency injection is a design pattern in which an object or function receives other objects or functions that it depends on. A form of inversion of control, dependency injection aims to separate the concerns of constructing objects and using them, leading to loosely coupled programs.

What is dependency injection with example?

Dependency injection (DI) is a technique widely used in programming and well suited to Android development. By following the principles of DI, you lay the groundwork for good app architecture. Implementing dependency injection provides you with the following advantages: Reusability of code.


1 Answers

You should use constructor injection instead of property injection if possible. This is a better technique, which is recommended by Mark Seeman, because makes dependencies required for object construction explicit and object signature via constructor is more expressive. Code should look like this:

    abstract class A
    {
        public IDependency Dependency { get; private set; }

        public A (IDependency dependency)
        {
            Dependency = dependency;
        }

    }

    class B : A
    {
        public B (IDependency dependency)
            : base(dependency)
        {

        }
    }

    class C : A
    {
        public C (IDependency dependency)
            : base(dependency)
        {

        }
    }

    interface IDependency { }

    class EmptyDependency : IDependency { }

    class ConcreteDependency : IDependency { }

Configuration will be the same as in you example. The following test passes

    [Test]
    public void TestSpecificBindingToObjectB()
    {
        var kernel = new StandardKernel(new TestModule());
        var b = kernel.Get<B>();
        var c = kernel.Get<C>();

        Assert.AreNotEqual(b.Dependency.GetType(), c.Dependency.GetType());
        Assert.AreEqual(typeof(ConcreteDependency), b.Dependency.GetType());
    }

If you have an optional dependency with default implementation and you are ok with decorating your classes with Inject attribute, you can can pull parent information from request, like this:

class TestModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDependency>().To<EmptyDependency>();
        Bind<IDependency>().To<ConcreteDependency>().When(req =>req.ParentContext.Request.Service == typeof(B));
    }
}

Then the same test given above passes for your class hierarchy with property injection.

like image 171
Ilya Ivanov Avatar answered Sep 30 '22 04:09

Ilya Ivanov