在库中解决应用程序之外的Unity依赖关系

时间:2014-01-06 08:31:23

标签: dependency-injection unity-container ioc-container

我正在构建一个ASP.NET MVC应用程序,并首次使用Unity实现依赖注入。对于一个特定的接口,我注册了多个类型,如下所示:

container.RegisterType<ICache, AppfabricCache>("AppfabricCache", new ContainerControlledLifetimeManager());
container.RegisterType<ICache, MemoryCache>("MemoryCache", new ContainerControlledLifetimeManager());

我现在需要根据CacheType枚举来决定使用哪一个。

我可以按照以下方式实现它,就像在Sixeyed.Caching项目中一样,但是它会让你在不同的地方注册类型。此外,您现在在容器周围有一个静态包装,感觉不干净。

public static class Cache
{
    private static readonly IUnityContainer _container;
    static Cache()
    {
        _container = new UnityContainer();
        _container.RegisterType<ICache, MemoryCache>("MemoryCache", new ContainerControlledLifetimeManager());
    }

    public static ICache Get(CacheType cacheType)
    {
        ICache cache = new NullCache();
        switch(cacheType)
        {
            case CacheType.Memory:
                cache = _container.Resolve<ICache>("MemoryCache");
                break;
            ...
            ...
        }
    }   
}

如何从我的应用程序中的其他库项目中获取容器?或者说,我如何从图书馆做这种解决方案?或许我不应该?

这个blog post表示将容器放在应用程序入口点之外并不是一个好主意,这听起来是正确的。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

正如@ploeh建议的那样,容器不应该在应用程序根目录之外知道 要根据运行时值获取实现,您应该使用工厂

public class CacheFactory : ICacheFactory 
{
    private readonly IUnityContainer _container;

    public CacheFactory(IUnityContainer container)
    {
        if (container == null) 
            throw new ArgumentNullException("container");

        _container = container;
    }

    public ICache Get(CacheType cacheType)
    {
        // implementation as in your post
    }
}

public class SomethingUsingTheCache
{
    private readonly ICacheFactory _cacheFactory;

    public SomethingUsingTheCache(ICacheFactory cacheFactory)
    {
        if (cacheFactory == null) 
            throw new ArgumentNullException("cacheFactory");

        _cacheFactory = cacheFactory;
    }

    public void DoStuff()
    {
        // get from config or wherever
        CacheType cacheType = CacheType.Memory;

        ICache cache = _cacheFactory.Get(cacheType);
        // do something with cache 
    }
}

工厂 放置在应用程序根 中,其他类使用 工厂< / strong>并且 容器没有概念。