我刚开始使用依赖注入。我已经阅读了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)));
}
}
但是你怎么能真正注入内核?需要什么样的映射?这甚至是正确的方法吗?
感谢您的帮助 费利克斯
答案 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方式(提供者)或多或少地执行您对自己的回答。你最好有充分的理由去做那么多的锅炉盘。