Unity扩展依赖注入容器

时间:2018-07-10 21:24:18

标签: c# dependency-injection inversion-of-control unity-container

我正在研究一个当前在整个代码中都使用Service Locator Anti-Pattern的项目。我正在开始逐步将所有内容转换为使用依赖注入的过程,但是由于项目规模庞大,我希望在一段时间内做到这一点。

我有一个自定义工厂,其自定义实现中注册了100多个依赖项。因此,我想用统一性包装我的容器,如果我当前的容器没有实现,那么请回退以使用统一性。

我已经编写了此类来包装IUnityContainer

public class GlobalFactoryUnityWrapper : IUnityContainer
{
    IUnityContainer _unityContainer = new UnityContainer();
    IUnityContainer _parent;

    public GlobalFactoryUnityWrapper(IUnityContainer parent = null)
    {
        this._parent = parent ?? this._unityContainer.Parent;
    }

    public IUnityContainer Parent => this._parent;

    //... Other IUnityContainer members

    public object Resolve(Type type, string name, params ResolverOverride[] resolverOverrides)
    {
        if(GlobalContext.InstanceFactory.CanGetInstance(type))
        {
            return GlobalContext.InstanceFactory.GetInstance(type);
        }

        return this._unityContainer.Resolve(type, name, resolverOverrides);
    }
}

我在那里有我的控制器的大多数依赖项寄存器,但是控制器本身没有,所以回退到使用unity的容器。

修改 我认为我使用的是错误的东西,应该使用策略。我的主要目标是如果容器不包含实现,请回退以使用旧容器中注册的内容

1 个答案:

答案 0 :(得分:0)

我需要创建一个后备策略,这可能不是最理想的代码,但目前可以使用

public class FactoryFallbackExtension : UnityContainerExtension
{
    public FactoryFallbackExtension()
    {
    }

    protected override void Initialize()
    {
        var strategy = new FallBackStrategy(Context);
        Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
    }
}
public class FallBackStrategy : BuilderStrategy
{
    private ExtensionContext baseContext;

    public FallBackStrategy(ExtensionContext baseContext)
    {
        this.baseContext = baseContext;
    }

    public override void PreBuildUp(IBuilderContext context)
    {
        var key = context.OriginalBuildKey;
        if (key.Type.IsInterface)
        {
            if(GlobalContext.InstanceFactory.CanGetInstance(key.Type))
                context.Existing = GlobalContext.InstanceFactory.GetInstance(key.Type);    
        }
    }
}

然后,当我配置容器时,可以像这样添加容器扩展名:

public static void Configure()
{
    var container = new UnityContainer();
    RegisterDepedencies(container);
    container.AddExtension(new FactoryFallbackExtension());
    GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    SetControllerFactory(container);
}