我有一个通用接口IService
,具体由三个或四个实现实现。
public interface IService {
void HandleRequest( RequestData data );
}
public class AService : IService {
public void HandleRequest( RequestData data ) {
}
}
public class BService : IService {
public void HandleRequest( RequestData data ) {
}
}
选择具体实现与不同实现的规则实际上是在一个分析输入对象(RequestData
)的方法中实现的,并根据来自数据库的一些数据选择正确的具体类。
我现在需要在控制器类中进行构造函数注入,并希望配置Ninject来处理这些对象的实例创建,如下例所示
public class MyController : ApiController
{
private readonly IService _service;
public MyController( IService service ) {
_service = service;
}
}
有没有办法在决策过程中编写这样的扩展来支持Ninject?我在想这样的事情
Bind<IService>().To<AService>().IfConditionIsTrue( new CustomProvider() );
Bind<IService>().To<BService>().IfConditionIsTrue( new CustomProvider() );
public class CustomProvider {
public bool ApplyCustomLogic() {
RequestData rd = GetParameter();
[...]
//custom logic implementation here..
}
}
另外,我如何通过利用ninject功能来动态创建实例?例如,在特定时间的方法内,我需要一个IService
的实例。如何让ninject动态提供具体实例?到目前为止,我只使用构造函数注入。
答案 0 :(得分:2)
我认为你不应该污染&#39;您的DI配置。而是通过使用可以将RequestData
消息分派到正确的处理程序实现的代理类来解决此问题:
public sealed class ServiceDispatcher : IService
{
private readonly Kernel kernel;
public ServiceDispatcher(Kernel kernel) {
this.kernel = kernel;
}
public void HandleRequest(RequestData data) {
Type implementationType;
// custom logic to determine correct IService based on data here..
// and resolve that implementation from the kernel.
IService realService = (IService)this.kernel.Get(implementationType);
realService.HandleRequest(data);
}
}
现在,您可以将ServiceDispatcher
课程绑定到IService
,并允许将其注入依赖IService
的任何人。调度程序将确保将请求分派给正确的实现。
但您可能需要考虑使用通用抽象,例如IService<T>
。例如,请查看this article。