是否可以同时使用具有不同类型配置的 ICacheManager<>?

Is it possible to use ICacheManager<> with different type of configurations at the same time?

假设我有像下面这样的接口,它们都继承自 ICacheManager<>

public interface ICacheManagerRuntime<T> : ICacheManager<T>
public interface ICacheManagerRedis<T> : ICacheManager<T>
public interface ICacheManagerRedisWithRuntime<T> : ICacheManager<T>

我想注入 ICacheManager{CacheType} 接口来实现 Cache 类,例如:

CacheRuntime, CacheRedis, CacheRedisWithRuntime

为了团结,我想像下面这样注入它们:

container.RegisterType<ICacheManagerRuntime<object>>(
                new ContainerControlledLifetimeManager(),
                new InjectionFactory((c, t, n) =>
                {
                    return CacheFactory.Build... // Return CacheManager just with RuntimeCacheHandle
                })));


container.RegisterType<ICacheManagerRedis<object>>(
                new ContainerControlledLifetimeManager(),
                new InjectionFactory((c, t, n) =>
                 {
                    return CacheFactory.Build... // Return CacheManager just with RedisCacheHandle
                })));


container.RegisterType<ICacheManagerRedisWithRuntime<object>>(
                new ContainerControlledLifetimeManager(),
                 {
                    return CacheFactory.Build... // Return CacheManager just with RuntimeCacheHandleWithRedisBackPlane
                })));

无论我做了什么,我都遇到了这个异常:

An unhandled exception of type 'Microsoft.Practices.Unity.ResolutionFailedException' occurred in Microsoft.Practices.Unity.dll

Additional information: Resolution of the dependency failed, type = "Solid.Play.Business.Interfaces.IProductService", name = "(none)".

Exception occurred while: Resolving parameter "cache" of constructor Solid.Play.Cache.Caches.CacheRuntime(Solid.Play.Cache.Interfaces.ICacheManagerRuntime`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] cache).

Exception is: InvalidCastException - Unable to cast object of type 'CacheManager.Core.BaseCacheManager`1[System.Object]' to type 'Solid.Play.Cache.Interfaces.ICacheManagerRuntime`1[System.Object]'.

-----------------------------------------------

At the time of the exception, the container was:



  Resolving Solid.Play.Business.Services.ProductService,(none) (mapped from Solid.Play.Business.Interfaces.IProductService, (none))

    Resolving Solid.Play.Cache.Interception.CachingInterceptorBehavior,(none)

    Resolving parameter "cache" of constructor Solid.Play.Cache.Interception.CachingInterceptorBehavior(Solid.Play.Cache.Interfaces.ICacheSolid cache)

      Resolving Solid.Play.Cache.Caches.CacheSolid,(none) (mapped from Solid.Play.Cache.Interfaces.ICacheSolid, (none))

      Resolving parameter "cacheRuntime" of constructor Solid.Play.Cache.Caches.CacheSolid(Solid.Play.Cache.Interfaces.ICacheRuntime cacheRuntime, Solid.Play.Cache.Interfaces.ICacheRedis cacheRedis, Solid.Play.Cache.Interfaces.ICacheRedisWithRuntime cacheRedisWithRuntime)

        Resolving Solid.Play.Cache.Caches.CacheRuntime,(none) (mapped from Solid.Play.Cache.Interfaces.ICacheRuntime, (none))

        Resolving parameter "cache" of constructor Solid.Play.Cache.Caches.CacheRuntime(Solid.Play.Cache.Interfaces.ICacheManagerRuntime`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] cache)

转换无效,因为您正试图将实例转换为它未实现的接口。 简化后,您正在尝试的内容如下所示:

public interface IBase
{
}

public interface ISub : IBase { }

public class BaseClass : IBase
{
}

var sub = (ISub)new BaseClass();

如果你想注入相同接口的不同类型的实例,Unity DI 框架提供了一种通过命名注入来实现的方法。

示例:

        container.RegisterType<ICacheManager<object>>("runtimeCache",
        new ContainerControlledLifetimeManager(),
        new InjectionFactory((c, t, n) =>
        {
            return CacheFactory.Build<object>(s =>
            {
                s.WithSystemRuntimeCacheHandle("cache.runtime");
            });
        }));

        container.RegisterType<ICacheManager<object>>("redisCache",
        new ContainerControlledLifetimeManager(),
        new InjectionFactory((c, t, n) =>
        {
            return CacheFactory.Build<object>(s =>
            {
                s.WithRedisConfiguration("cache.redis", config =>
                {
                    config
                    .WithAllowAdmin()
                    .WithDatabase(0)
                    .WithEndpoint("localhost", 6379);
                })
                .WithRedisCacheHandle("cache.redis");
            });
        }));

要解决第一个问题,您需要使用

var runtimeCache = container.Resolve<ICacheManager<object>>("runtimeCache");

例如,您可以将 ICacheManager 接口注入具有属性的构造函数。

public YourClass([Dependency("runtimeCache")] ICacheManager<object> cache)
{

}