获取所有已注册的通用类

时间:2016-08-11 07:21:46

标签: c# generics dependency-injection asp.net-core

在我们的ASP.NET核心项目中,我们在DI中注册了用于缓存管理的泛型类。通过这种方式,我们可以按照我们注入的通用参数在逻辑部分中对缓存进行分区。

services.AddSingleton(typeof(IMemoryCacheManager<>), typeof(MemoryCacheManager<>));

我们这样注入:

IMemoryCacheManager<Class1> cache
IMemoryCacheManager<Class2> cache

但有时我需要一次获取IMemoryCacheManager的所有实例,以清除缓存(例如)。我可以用DI来实现这个目标吗?

编辑1 这段代码编译:

var services =_serviceProvider.GetServices(typeof(IMemoryCacheManager<>));

foreach (ICacheManager item in services)
    item.Clear();

但我有这个例外:提供的通用参数的数量不等于通用定义类型的arity

1 个答案:

答案 0 :(得分:1)

我通过创建一个CacheTracker类(作为单例)来解决它,它在实例化时跟踪缓存类。这是代码,也许它可以帮助。

CacheTracker.cs

public class CacheTracker : ICacheTracker
{
    private readonly IList<ICacheManager> _cacheList;

    public CacheTracker()
    {
        this._cacheList = new List<ICacheManager>();
    }

    public void AddCache(ICacheManager cache)
    {
        this._cacheList.Add(cache);
    }

    public IReadOnlyList<ICacheManager> GetCaches(Type cacheType)
    {
        var caches =
                        from cache in _cacheList
                        where
                            cache.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == cacheType) &&
                            cache.GetType().IsClass
                        select cache;

        return caches
            .ToList()
            .AsReadOnly();
    }
}

ICacheTracker.cs

public interface ICacheTracker
{
    IReadOnlyList<ICacheManager> GetCaches(Type cacheType);
    void AddCache(ICacheManager cache);
}

在每个缓存实现中

public MemoryCacheManager(...
        ICacheTracker cacheTracker)
{
    ...

    cacheTracker.AddCache(this);
}

当我需要使用所有缓存时

foreach (ICacheManager item in _cacheTracker.GetCaches(typeof(IMemoryCacheManager<>)))
    item.Clear();