向自己注册IOC容器 [英] Register IOC container to self

查看:79
本文介绍了向自己注册IOC容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个接口IDependencyResolver:

Let's say I have an interface IDependencyResolver:

public interface IDependencyResolver{
    T Resolve<T>() where T: class;
    object Resolve(Type source);
}

以及使用SimpleInjector的实现:

And an implementation with the use of 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注入使用Service locator模式的构造函数中,该怎么办? (是的,我知道。。。是反模式。。。)

What do I need to do if I need the IDependencyResolver injected in a constructor which uses the Service locator pattern? (yes, I know... an anti-pattern... but this aside)

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>>();
    }
}

过去,我总是将依赖解析器self注册为

In the past I always registered the dependency resolver self as a singleton, so not with a scoped lifestyle since that gave me problems.

container.Register<IDependencyResolver, SIDependencyResolver>(LifeStyle.Singleton);

首先,这是正确的方法吗(例如,在WCF范围内,单例生活方式吗?或者还有其他方法吗?

其次,将SimpleInjector.Container传递给我的DependentResolver的构造函数是否正确?

First of all, is this the correct way (for example in case of WCF scope, with a singleton lifestyle) to do this or is there another way to do this?
Second, is it correct to pass the SimpleInjector.Container to the constructor of my dependencyResolver?

推荐答案


如果我需要将IDependencyResolver注入使用Service locator模式的构造函数中,该怎么办? (是的,我知道...一个反模式...但是要放在一边)

What do I need to do if I need the IDependencyResolver injected in a constructor which uses the Service locator pattern? (yes, I know... an anti-pattern... but this aside)

这不应该放在一边。尽管您像在 UnitOfWork 中那样对容器进行回调的方法很好,但是($)这样的 IDependencyResolver的使用(滥用)抽象可以在代码库中快速传播到绝对不能使用的地方。

This should not be set aside. Although your approach of making the callback to the container like you're doing in your UnitOfWork is fine, the (ab)use of such IDependencyResolver abstraction can quickly spread out through the code base to places where it is absolutely not fine.

IDependencyResolver 抽象应限于组合根。但是,由于组合根已经知道您正在使用的确切DI库的存在,因此具有 IDependencyResolver 抽象对直接依赖没有好处。容器本身。

The usage of this IDependencyResolver abstraction should be limited to the composition root. But since the composition root already knows about the existence of the exact DI library you are using, having this IDependencyResolver abstraction has no benefit over depending directly on the Container itself.

因此,应在 inside <中定义您的 IUnitOfWork 实现。 / strong>您的撰写根目录,应如下所示:

So your IUnitOfWork implementation should be defined inside your Compostion Root and should look as follows:

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>>();
}

可以按照以下方式进行注册:

Registration can be done as follows:

container.RegisterSingleton<IUnitOfWork>(new SimpleInjectorUnitOfWork(container));




过去,我总是将依赖解析器self注册为单例,

In the past I always registered the dependency resolver self as a singleton, so not with a scoped lifestyle since that gave me problems.

我不清楚您遇到了什么问题,但有一件事情会解决引起麻烦的是在构造函数中设置了 DefaultScopedLifestyle ,而该类型由容器自动连接。最好将此调用移出此类构造函数。

It is unclear to me what problems you had, but one thing that will cause trouble is setting the DefaultScopedLifestyle inside a constructor, while the type is auto-wired by the container. It is much better to move this call out of such constructor; it makes it much clearer:

var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifeStyle();

这篇关于向自己注册IOC容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆