2010-08-30 39 views
1

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

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

但后来你如何能真正注入内核?需要什么映射?这甚至是正确的方法吗?作为建议由本杰明Podszun

感谢所有帮助 菲利克斯

回答

1

答案:

注入工厂:

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的特定实例。

+0

是的,我就是这么做的。 http://kozmic.pl/archive/2010/06/22/how-i-use-inversion-of-control-containers-ndash-pulling-from.aspx – 2010-08-31 02:11:52

0

你可以做到这一点非常干净:(exec summary of another answer re a slightly different question

Bind<Func<IContact>>().ToMethod(context =>() => Kernel.Get<Contact>()); 

您的其他选项有:

  • IKernel注入像你一样(这是支持开箱即用特殊的技巧) ,但正如你提到的,这很少是你想要的 - 这就等于服务地点。

  • 做一个全面的工厂。查看惯用Ninject方式(提供商)的其他答案,以便更多或更少地了解自己的答案。你最好有一个很好的理由来做这个数量的锅炉板。

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

and bound l ike this:

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

到目前为止它对我们工作得非常好。

+0

+1不错。我很确定要做一个'Bind(typeof(Func <>))。ToMethod(context =>()=> context.Get(context.Service))'也可以工作(尽管我可能会跟你一样这很好,很明确)。另外,如果人们感兴趣,那么在源代码中有一些测试/示例重新绑定这样的开放泛型。 – 2010-09-01 07:51:07

+0

是的,绑定一个Func可以让你跳过界面,并且可以使测试更容易。我们最终实现了一个'FunctionBasedFactory'来实现它,所以我们可以使用Func在单元测试中注入工厂。但我更喜欢使用依赖接口。 – StriplingWarrior 2010-09-01 15:23:46