我们说我有一个接口IDependencyResolver:
public interface IDependencyResolver{
T Resolve<T>() where T: class;
object Resolve(Type source);
}
使用SimpleInjector的实现:
public class SIDependencyResolver:IDependencyResolver{
private readonly Container _container;
public SIDependencyResolver(Container container){
_container = container;
_container.Options.DefaultScopedLifestyle = new WcfOperationLifeStyle();
RegisterDependencies(_container, LifeStyle.Scoped);
}
public T Resolve<T>() where T:class{
return _container.GetInstance<T>();
}
public object Resolve(Type source){
return _container.GetInstance(source);
}
public void RegisterDependencies(Container container, LifeStyle lifeStyle){
//register dependencies + register self
}
}
如果我需要在使用服务定位器模式的构造函数中注入IDependencyResolver,我该怎么办? (是的,我知道......反模式......但除此之外)
public class UnitOfWork: IUnitOfWork{
private readonly IDependencyResolver _resolver;
public UnitOfWork(IDependencyResolver resolver){
_resolver = resolver;
}
public IReadRepository<T> Read<T>(){
return _resolver.Resolve<IReadRepository<T>>();
}
public IWriteRepository<T> Write<T>(){
return _resolve.Resolve<IWriteRepository<T>>();
}
}
在过去,我总是将依赖性解析器自我注册为单身人士,因此没有采用范围生活方式,因为这给我带来了问题。
container.Register<IDependencyResolver, SIDependencyResolver>(LifeStyle.Singleton);
首先,这是正确的方法(例如在WCF范围的情况下,单身生活方式)这样做还是有其他方法可以做到这一点?
第二,将SimpleInjector.Container传递给dependencyResolver的构造函数是否正确?
答案 0 :(得分:2)
如果我需要在使用服务定位器模式的构造函数中注入IDependencyResolver,我该怎么办? (是的,我知道......反模式......但除此之外)
这不应该被搁置。尽管你在UnitOfWork
中对你的容器进行回调的方法很好,但这种IDependencyResolver
抽象的(ab)使用可以通过代码库快速传播到地方绝对不好的地方。
此IDependencyResolver
抽象的使用应限于组合根。但是由于组合根已经知道你正在使用的确切DI库的存在,所以IDependencyResolver
抽象没有直接依赖于Container
本身的好处。
因此,您的IUnitOfWork
实现应该在内部的Compostion Root中定义,并且应该如下所示:
private sealed class SimpleInjectorUnitOfWork : IUnitOfWork {
private readonly Container _container;
public UnitOfWork(Container container){
_container = container;
}
public IReadRepository<T> Read<T>() => _container.GetInstance<IReadRepository<T>>();
public IWriteRepository<T> Write<T>() => _container.GetInstance<IWriteRepository<T>>();
}
注册可以按如下方式进行:
container.RegisterSingleton<IUnitOfWork>(new SimpleInjectorUnitOfWork(container));
在过去,我总是将依赖性解析器自我注册为单身人士,因此没有采用范围生活方式,因为这给我带来了问题。
我不清楚你遇到了什么问题,但有一件事会引起麻烦,那就是在构造函数中设置DefaultScopedLifestyle
,而类型是由容器自动连接的。将此调用移出此类构造函数要好得多;它使它更清晰:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifeStyle();