简体   繁体   English

从类库访问Web应用程序的统一容器

[英]Accessing unity container of web app from a class library

I have a class library for caching ( Redis ), we have a unity container inside this Redis class library 我有一个用于缓存的类库(Redis),在这个Redis类库中有一个统一的容器

public class TCache<T>
{
    static readonly IUnityContainer container = new UnityContainer();

    private ITCache<T> ICacheStore;
    static TCache()
    {
        container.RegisterType<ITCache<T>, TRedisCacheStore<T>>(new ContainerControlledLifetimeManager());
    }
    public TCache()
    {
        ICacheStore = container.Resolve<TRedisCacheStore<T>>();
    }

Now my senior said me not use a separate container like this and I should be using the container which is already created inside the web app with the reason being that there should be only one single container. 现在我的长辈说我不使用这样的单独容器,我应该使用已经在Web应用程序内部创建的容器,原因是应该只有一个容器。

My question is: is it possible to access a unity container that resides in a different project and is it necessary to do this change ? 我的问题是:是否可以访问驻留在其他项目中的统一容器,是否有必要进行此更改?

Note: I cannot add the reference of the web app into the Redis cache class library. 注意:我无法将Web应用程序的引用添加到Redis缓存类库中。

Well, I share his view of the usage of the container. 好吧,我同意他对容器使用的看法。 How I fixed this issue is (without going into the details of how I actually created it): 我如何解决此问题(无需深入了解如何实际创建此问题):

Make an option to register onto the container through an interface. 选择一个通过接口注册到容器的选项。 Something like IRegisterContainer.Register(IUnityContainer container). 类似于IRegisterContainer.Register(IUnityContainer容器)。

Then at the moment where you now register the mappings to the container, you extend that function to also search your assembly for all objects that implement that IRegisterContainer and make them register themselves. 然后,在现在将映射注册到容器的那一刻,您可以扩展该功能以在程序集中搜索实现该IRegisterContainer的所有对象,并使它们自行注册。

And use this as a platform to fix your problem. 并以此为平台来解决您的问题。

If you want to use the IUnityContainer in your TCache object to resolve the TRediscacheStore. 如果要在TCache对象中使用IUnityContainer来解析TRediscacheStore。 Simply let the IUnityContainer register itself. 只需让IUnityContainer注册即可。

container.Register<IUnityContainer, container>(). 

And make it a dependency in the constructor of TCache. 并使其成为TCache构造函数中的依赖项。

You should only reference a container within your composition root ( http://blog.ploeh.dk/2011/07/28/CompositionRoot/ ). 您只应在合成根目录http://blog.ploeh.dk/2011/07/28/CompositionRoot/ )中引用一个容器。

In other words, find where your current services are registered, and perform the generic registration there. 换句话说,找到您当前服务的注册位置,然后在此处进行通用注册。

Your type that requires a cache store then takes your abstraction via constructor injection: 您需要缓存存储的类型然后通过构造函数注入进行抽象:

public class Cache<T>
{
  private readonly ITCache<T> cacheStore;

  public Cache(ITCache<T> cacheStore)
  {
      this.cacheStore = cacheStore 
          ?? throw new ArgumentNullException(nameof(cacheStore));
  }
}

By the way, using T as a prefix for your types (rather than as a prefix for generic type parameters) is very confusing. 顺便说一下,使用T作为类型的前缀(而不是作为通用类型参数的前缀)非常令人困惑。

The names TCache and ITCache are also very confusing. TCacheITCache的名称也非常令人困惑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM