Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject different classes that implement the same interface using Ninject

Tags:

c#

ninject

I am implementing the builder design pattern to construct different kinds of graph objects to be displayed on a WPF UI. I am using Ninject as my IOC container. However, I am trying to find an elegant extendable solution.

I have a ChartDirector object that takes a IChartBuilder as a dependency. I also have TemperatureChartBuilder and ThresholdChartBuilder that implement IChartBuilder. I want to inject either TemperatureChartBuilder OR ThresholdChartBuilder to ChartDirector depending on an event that is fired or depending on a client call. I have illustrated my problem below in code.

// ChartDirector also depends on this
kernel.Bind<IExample>().To<Example>();

// when called in Method X...
kernel.Bind<IChartBuilder>().To<TemperatureChartBuilder>();

// when called in Method Y...
kernel.Bind<IChartBuilder>().To<ThresholdChartBuilder();

// TemperatureChartBuilder is a dependency of ChartDirector, need a way to dynamically
// allocate which binding to use.
var director = kernel.Get<ChartDirector>();

// without Ninject I would do
var director = new ChartDirector(new TemperatureChartBuilder);

// or
var director = new ChartDirector(new ThresholdChartBuilder);

EDIT:

Coupled with Gary's answer, and noting a slight edit that ChartDirector has another dependency, I now want to do something like this:

var director = kernel.Get<ChartDirector>().WithConstructorArgument(kernel.Get<IChartBuilder>("TemperatureChart"));

Is something like this possible?

like image 327
Seth Avatar asked Dec 21 '11 05:12

Seth


People also ask

What is ninject dependency injection?

Ninject is a lightweight dependency injection framework for . NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner.

How does Dependency Injection work?

Dependency injection is a programming technique that makes a class independent of its dependencies. It achieves that by decoupling the usage of an object from its creation. This helps you to follow SOLID's dependency inversion and single responsibility principles.

Why Dependency Injection?

In Java, before we can use methods of other classes, we first need to create the object of that class (i.e. class A needs to create an instance of class B). So, transferring the task of creating the object to someone else and directly using the dependency is called dependency injection.

What is a ninject module?

The Ninject modules are the tools used to register the various types with the IoC container. The advantage is that these modules are then kept in their own classes. This allows you to put different tiers/services in their own modules.


Video Answer


1 Answers

If you're just planning to use service location, as in your examples, then named bindings work fine, as per Garys answer.

A better approach, however, is to use constructor injection, and use attributes. For exampl, from the ninject wiki:

Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak"); 

...

class WeakAttack {
    readonly IWeapon _weapon;
    public([Named("Weak")] IWeapon weakWeapon)
        _weapon = weakWeapon;
    }
    public void Attack(string victim){
        Console.WriteLine(_weapon.Hit(victim));
    }
}

Based on your comment to Gary, you're (strangely enough) stumbling into territory similar to what I asked a question about a few hours ago. See Remo's answer here: Using WithConstructorArgument and creating bound type

You would use When condition to define when to create the correct instance.

like image 75
Erik Funkenbusch Avatar answered Oct 13 '22 02:10

Erik Funkenbusch