使用Ninject基于字符串创建对象

时间:2015-04-14 18:36:09

标签: c# dependency-injection ninject

我需要根据从数据库中获取的字符串创建共享公共接口(IFoo)的对象。我有" A",我需要填写AFoo,我得到" B",我需要生产BFoo等。我应该做的第一件事是工厂。但是创建的对象(AFoo,BFoo)需要注入其依赖项(并且这些依赖项需要更多的依赖项和一些偶数参数)。对于所有注射我使用Ninject,它本身似乎是一个奇特的工厂。要在我的工厂内创建对象,我通过构造函数注入Ninject的内核。这是理想的方式吗?

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");
    }
}

1 个答案:

答案 0 :(得分:7)

Ninject的IKernel的{​​{1}}方法有一个重载,它使用name参数来获取命名实例。

用法是:

Get<T>()

关于将Ninject的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"); } 注入IKernel的构造函数的问题,我不认为应该有任何问题。 你的工厂应该是这样的:

Factory

此外,你可以像这样添加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); } } 的绑定:

IKernel