【问题标题】:Resolving Unity dependency outside of application start, in libraries在库中解决应用程序启动之外的 Unity 依赖关系
【发布时间】:2014-01-06 08:31:23
【问题描述】:

我正在构建一个 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 表示将容器放在应用程序入口点之外并不是一个好主意,这听起来是正确的。这样做的正确方法是什么?

【问题讨论】:

  • 您需要如何以及何时在 ICache 实现之间进行选择/切换?这是基于 web.config 设置吗?基于一些程序逻辑?
  • @Steven 程序逻辑 - 一个进程内缓存(如 1 级)和一个进程外缓存(2 级)。但是,嘿,即使我只有一种类型的缓存(很可能),我也想在不同的地方简单地使用它。我不想在所有要使用缓存的地方通过构造函数传递 ICache。
  • 为什么不想使用构造函数注入?如果你需要在很多地方注入它,你可能违反了单一职责原则。缓存是一个横切关注点,最好使用拦截或修饰来添加。

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


【解决方案1】:

正如@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 
    }
}

工厂放置在应用程序根,任何其他类使用工厂 并且没有 容器的概念。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2019-06-04
  • 2012-02-22
  • 1970-01-01
相关资源
最近更新 更多