2016-06-08 38 views
3

我正在处理内存缓存应用程序,可以通过配置加载不同的缓存提供程序。我通过定义接口并使用插件模型来加载解析文件并加载与接口相匹配的类的程序集和类来完成此任务。我真的很想定义接口和一个允许任何对象被支持缓存存储的通用类型(无论它是像Redis或NCache这样的第三方缓存客户端的包装器,还是我自己的MemoryCache实现等)有一个工厂的最终目标,我可以指出一个dll包装我的缓存方法。泛型,接口和激活器

当我使用Activator尝试实例化插件时,我遇到的问题是有关泛型的错误。有没有人知道一种方法来加载类与泛型到一个接口?

基本接口

public interface ICacheProvider<T> 
{ 
    T Get(string key); 
    bool Set(string key, T value, TimeSpan expiration); 
} 

工厂调用加载

public static ICacheProvider<T> GetCacheProvider(string path, string className, string configuration) 
{    
    ... 
    Assembly asm = Assembly.LoadFile(path); 
    Type type = asm.GetType(className); 

    return Activator.CreateInstance(type, new object[] { configuration }) as ICacheProvider<T>; 
    ... 
} 

回答

6

很抱歉,但我不认为这是很好的设计(我知道这是不是代码审查SE)。

ICacheProvider<T>不是很好用,因为没有什么需要为每个可缓存对象分别输入类型。以下是,国际海事组织,好多了,再加上它免除了您CreateInstance头痛:

public interface ICacheProvider 
{ 
    T Get<T>(string key); 
    bool Set<T>(string key, T value, TimeSpan expiration); 
} 

的进一步深入,我肯定不只这与普通object小号ICacheProvider工作,无论其具体类型的具体实现。有了这个,你可以进一步简化您的合同:

public interface ICacheProvider 
{ 
    object Get(string key); 
    bool Set(string key, object value, TimeSpan expiration); 
} 

和一对夫妇的扩展方法:

public static class CacheProviderExtensions 
{ 
    public static T Get<T>(this ICacheProvider cacheProvider, string key); 
    public static bool Set<T>(this ICacheProvider cacheProvider, string key, 
     T value, TimeSpan expiration); 
} 

现在,缓存中的最常见的操作之一是“GET-或加”行为,它可以表示为另一种方法ICacheProvider

object GetOrSet(string key, Func<object> valueProvider, TimeSpan expiration) 
+0

具体的实现使用普通对象是正确的。 请记住,这里的示例代码片段实际上简化了他们的实际情况,以便为我尝试实现的一个快速示例。 我在初始化时定义类型的意图是将特定的缓存实例限制为某种类型。基本上,如果我说了一个用户对象的缓存,我想限制某人向缓存实例添加其他内容的可能性。扩展方法并不是一个坏主意,尽管我觉得它不像明确指定缓存类型那样具有错误抵抗力。 – JMorgan

+0

@ anton-gogolev为什么在代码实际上是你的时候使用'extension'方法? –