Ninject - 如何在对象生命周期内注入?

时间:2010-08-30 09:42:55

标签: c# dependency-injection ninject

我刚开始使用依赖注入。我已经阅读了Ninject wiki,并且非常清楚如何使用构造函数,属性或方法注入来注入需要依赖的单个实例的依赖项。但是,如何处理类在其生命周期内(构造后)需要构造对象的情况?例如:

class AddressBook
{
    private List<IContact> _contacts;

    public AddContact(string name)
    {
        _contacts.Add(****what?****)
    }
}

我能想到的唯一方法是使用构造函数注入来传入IKernel并使用它来获取我们的IContact:

class AddressBook
{
    private IKernel _kernel;
    private List<IContact> _contacts;

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

    public AddContact(string name)
    {
        _contacts.Add(_kernel.Get<IContact>(new Parameter("name", name)));
    }
}

但是你怎么能真正注入内核?需要什么样的映射?这甚至是正确的方法吗?

感谢您的帮助 费利克斯

3 个答案:

答案 0 :(得分:2)

与其他人的回答类似,我们使用通用的IFactory接口:

public interface IFactory<T> 
{
    T Get();
}

可以这样使用:

public AddressBook(IFactory<IContact> ContactFactory)

然后像这样实施:

public class InjectorFactory : IFactory<T> 
{
    // we wrapped the Kernel in an Injector class
    public T Get() { return Injector.Get<T>(); } 
}

并且这样绑定:

Bind(typeof(IFactory<>)).To(typeof(InjectorFactory<>))

到目前为止,它对我们来说非常有效。

答案 1 :(得分:1)

Benjamin Podszun建议的答案:

注入工厂:

public interface IContactFactory
{
    IContact CreateContact(string name);
}

class AddressBook
{
    private IContactFactory _factory;
    private List<IContact> _contacts;

    public AddressBook(IContactFactory factory){ _factory = factory; }        

    public AddContact(string name)
    {
        _contacts.Add(_factory.CreateContact(name));
    }
}

然后,您可以将工厂绑定到您想要创建任何特定IContact实例的任何内容。

答案 2 :(得分:0)

你可以用:( exec summary of another answer re a slightly different question

非常干净地完成
Bind<Func<IContact>>().ToMethod( context => () => Kernel.Get<Contact>() );

您的其他选择是:

  • 像你一样注入了IKernel(这有任何特殊技巧支持OOTB),但正如你所说,这很少是你想要的 - 这等于服务地点。

  • 做一个全面的工厂。请参阅其他答案,了解惯用的Ninject方式(提供者)或多或少地执行您对自己的回答。你最好有充分的理由去做那么多的锅炉盘。