Ninject、Providers 和 Activator.CreateInstance
我对 Ninject 相当陌生,但我已经成功地使用自定义提供程序将其用于 DI。
绑定初始化如下
kernel = new StandardKernel();
kernel.Bind<IPatientRecordLocator>().ToProvider<PatientRecordLocatorProvider>();
,在自定义提供程序中,我像这样调用 Activator.CreateInstance
protected override IPatientRecordLocator CreateInstance(IContext context)
{
var name = ConfigurationManager.AppSettings["PatientRecordLocator"];
var typeName = name.Split(',')[0];
var assemblyName = name.Split(',')[1];
return Activator.CreateInstance(assemblyName, typeName).Unwrap() as IPatientRecordLocator;
}
(是的,我知道上面的代码中没有错误处理等:))
,所有这些都像魅力一样。
现在,我面临的问题是当我引入一个新类时,我希望将其注入 IPatientRecordLocator 的实例中。当我将如下所示的构造函数添加到这些类之一时,就会出现问题
[Inject]
public MockPatientRecordLocator (IContactAdapter contactAdapter)
{
...
}
然后,为了 Activator.CreateInstance 工作,我还必须向 MockPatientRecordLocator 类添加一个无参数构造函数,即
public MockPatientRecordLocator()
{
}
所以,我的问题是:如何使 Ninject 注入将 IContactAdapter 实现为 MockPatientRecordLocator 的类的实例?我尝试过方法注入,但没有成功。
我忘记解释我想要实现的是一种链式注入,其中类 PatientRecordSummary 的实例被注入 MockPatientRecordLocator 的实例(使用构造函数注入),并且所述 MockPatientRecordLocator 的实例应该被注入 IContactAdapter 的实例(再次使用构造函数注入(如果可能))。链条的第一部分有效,第二部分则无效。
I'm fairly new to Ninject, but I have successfully managed to use it for DI using a custom provider.
The binding is initialised as follows
kernel = new StandardKernel();
kernel.Bind<IPatientRecordLocator>().ToProvider<PatientRecordLocatorProvider>();
and in the custom provider I call Activator.CreateInstance like so
protected override IPatientRecordLocator CreateInstance(IContext context)
{
var name = ConfigurationManager.AppSettings["PatientRecordLocator"];
var typeName = name.Split(',')[0];
var assemblyName = name.Split(',')[1];
return Activator.CreateInstance(assemblyName, typeName).Unwrap() as IPatientRecordLocator;
}
(yes, I am aware that there is no error handling, etc. in the code above :) )
and all this works like a charm.
Now, the problem I'm facing is when I introduce a new class that I wish to inject into instances of IPatientRecordLocator. The problem occurs when I add a constructor like the following to e.g. one of these classes
[Inject]
public MockPatientRecordLocator (IContactAdapter contactAdapter)
{
...
}
Then, for Activator.CreateInstance to work I also have to add a parameterless constructor to class MockPatientRecordLocator, i.e.
public MockPatientRecordLocator()
{
}
So, my question is: how can I make Ninject inject an instance of a class that implements IContactAdapter into e.g. MockPatientRecordLocator? I've tried method injection, but to no avail.
I forgot to explain that what I'm trying to achieve is a kind of chained injection where an instance of class PatientRecordSummary gets injected with an instance of MockPatientRecordLocator (using constructor injection) and said instance of MockPatientRecordLocator should get injected with an instance of IContactAdapter (again using constructor injection (if possible)). The first part of the chain works, the second doesn't.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于第一个问题来说还不错!
您希望使用
Bind(Type)
重载来允许注册在Load()
代码上下文中没有静态可用的内容 - 执行您的操作预先在您的提供程序中进行操作(即解析类型
)。这将允许 Ninject 进行对象实例化(无需默认 .ctor)IIRC 我最近的两个或三个答案也涉及到这个发现/加载的内容,并且有应该与您的案例相关的示例。
(当你要删除东西时,你不需要求助于
[Inject]
属性)Not bad for a first question!
You want to use the
Bind(Type)
overload to allow registration of stuff that you dont have statically available in the context of yourLoad()
code - do the stuff you're doing in your provider (i.e., resolving theType
) up-front. This will allow Ninject to do the object instantiation (without any requirement for a default .ctor)IIRC two or 3 of my most recent answers also touch on this discovery/loading stuff, and have examples that should be relevant to your case.
(And you wont need to resort to
[Inject]
attributes when you've gotten to remove things)