2016-06-08 95 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'方法? –