我有一个抽象工厂,它创建一些服务,用IService
接口表示。在工厂中,我有两种方法,因为在其中一个方法中,我允许消费者传递现有的IServiceLogger
实例以供构造的服务树使用。将依赖项实例传递给工厂方法参数以使Ninject在分辨率范围内使用它
public interface IMyServiceFactory {
IMyService Create(IServiceLogger loggerInstance);
IMyService Create();
}
因为一个IServiceLogger
应该在服务树之间共享,我用的是InCallScope
绑定到具体实施的时候。
我该如何使用Ninject实现这个场景?我尝试了以下方法。
1.手动创建一个工厂实现
internal class MyServiceFactory : IMyServiceFactory {
private IResolutionRoot _kernel;
public MyServiceFactory
public IMyService Create(IServiceLogger loggerInstance) {
// what should go here? how can I pass the existing instance to Ninject Get method and make Ninject to use it for the whole resolution tree, just as it were created by Ninject and used as InCallScope?
}
// this one is trivial...
pulbic IMyService Create() {
return _kernel.Get<IMyService>();
}
}
UPDATE
其实我已经找到了这样的混乱和不太安全的方式。我可以通过GetBindings
,然后Rebind
IServiceLogger
ToConstant
,然后Get
,IMyService
实例获得当前绑定,最后用AddBinding
恢复原始绑定。我不喜欢它,它感觉很臭,更糟糕的是,它不是线程安全的,因为另一个线程可以在此代码中请求IMyService
,因此使用本地临时绑定。
2.使用Ninject.Extensions.Factory
只需使用ToFactory
约束力,但是这不工作,因为它只是尝试使用参数作为一个简单的构造函数的参数(如适用),而不是作为整个分辨率树的一个对象。
谢谢你的回答。你所描述的非常简单,甚至不需要IMO代码,因为就简单的一级构造函数而言,Factory扩展可以完成这项工作(正如我在文章中提到的那样)。当1:记录器MIGHT可选时,问题出现了2.记录器应该被完整的服务树使用,而不仅仅是在顶层。然而,我发现了一个解决方案,我很快就会发布。 –
哦,好的。然后我会推荐使用条件绑定,这在ninject中是相当强大的。 –