Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating objects based on a string using Ninject

I need to create objects sharing common interface (IFoo) based on a string I get from the database. I have "A", I need to intantiate AFoo, I get "B", I need to produce BFoo, etc. The first thing I tought of was a factory. But the objects created (AFoo, BFoo) need to have their dependencies injected (and those dependencies need more dependencies and some even arguments). For all the injecting I use Ninject, which by itself seems to be a fancy factory. To create objects within my factory I inject a Ninject's kernel via constructor. Is that the desired way?

interface IBar { }

class Bar : IBar {
    public Bar(string logFilePath) { }
}

interface IFoo { }

class AFoo : IFoo {
    public AFoo(IBar bar) { }
}

class BFoo : IFoo { }

class FooFactory : IFooFactory { 
    private IKernel _ninjectKernel;

    public FooFactory(IKernel ninjectKernel) {
        _ninjectKernel = ninjectKernel;
    }

    IFoo GetFooByName(string name) {
          switch (name) {
               case "A": _ninjectKernel.Get<AFoo>();
          }
          throw new NotSupportedException("Blabla");
    }
}

class FooManager : IFooManager {
    private IFooFactory _fooFactory;

    public FooManager(IFooFactory fooFactory) {
        _fooFactory = fooFactory;
    }

    void DoNastyFooThings(string text) {
        IFoo foo = _fooFactory.GetFooByName(text);
        /* use foo... */
    }
}

class Program {
    public static void Main() {
        IKernel kernel = new StandardKernel();
        kernel.Bind<IBar>.To<Bar>();
        kernel.Bind<IFooManager>.To<FooManager>();
        kernel.Bind<IFooFactory>.To<FooFactory>();
        IFooManager manager = kernel.Get<IFooManager>(new ConstructorArgument("ninjectKernel", kernel, true));
        manager.DoNastyFooThings("A");
    }
}
like image 527
user1713059 Avatar asked Apr 14 '15 18:04

user1713059


People also ask

What is ninject used for?

Why use Ninject? 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 glues them back together in a flexible manner.

What is ninject DLL?

Ninject helps you use the technique of dependency injection to break your applications into loosely-coupled, highly-cohesive components, and then glue them back together in a flexible manner.

How does dependency injection work?

Dependency Injection (DI) is a design pattern used to implement IoC. It allows the creation of dependent objects outside of a class and provides those objects to a class through different ways. Using DI, we move the creation and binding of the dependent objects outside of the class that depends on them.

Why is dependency injection useful?

Dependency injection helps to develop testable code, allowing developers to write unit tests easily. You can use mock databases with dependency injection, and test your application without affecting the actual database.


1 Answers

Ninject's IKernel's Get<T>() method has an overload which takes an name argument to get a named instance.

The usage would be:

public int Main()
{
    IKernel kernel = new StandardKernel();

    kernel.Bind<IFoo>().To<AFoo>().Named("AFoo");
    kernel.Bind<IFoo>().To<BFoo>().Named("BFoo");

    //returns an AFoo instance
    var afoo = kernel.Get<IFoo>("AFoo");

    //returns an BFoo instance
    var bfoo = kernel.Get<IFoo>("BFoo"); 
}

Regarding your question about injecting Ninject's IKernel into the Factory's constructor, I don't think there should be any problems. Your factory should look like this:

public interface IFooFactory
{
    IFoo GetFooByName(string name);
}

public class FooFactory : IFooFactory
{
    private readonly IKernel _kernel;

    public FooFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public IFoo GetFooByName(string name)
    {
        return _kernel.Get<IFoo>(name);
    }
}

Also you could add a binding to IKernel like this:

kernel.Bind<IKernel>().ToConstant(kernel);
like image 53
Maximo Dominguez Avatar answered Nov 15 '22 08:11

Maximo Dominguez