我正在开发一个内存缓存应用程序,可以通过配置加载不同的缓存提供程序.我这样做是通过定义一个接口并使用插件模型来加载一个解析文件并加载一个与接口匹配的类的程序集和类.我真的想定义接口和一个泛型类型,它允许任何对象由后备缓存存储(无论是第三方缓存客户端的包装,如Redis或NCache,还是我自己的MemoryCache实现等).有一个工厂的最终目标,我可以指向一个包含我的缓存方法的DLL.
当我使用Activator尝试实例化插件时,我遇到的问题是Generics的错误.有没有人知道将泛型加载到接口的方法?
基本界面
public interface ICacheProvider<T>
{
T Get(string key);
bool Set(string key, T value, TimeSpan expiration);
}
Run Code Online (Sandbox Code Playgroud)
工厂要求加载
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>;
...
}
Run Code Online (Sandbox Code Playgroud)
对不起,我不认为这是好设计(我知道这不是CodeReview SE).
ICacheProvider<T>
并不是很有用,因为它中没有任何内容需要为每个可缓存对象提供单独的类型.以下是,IMO,更好,加上它让你CreateInstance
头疼:
public interface ICacheProvider
{
T Get<T>(string key);
bool Set<T>(string key, T value, TimeSpan expiration);
}
Run Code Online (Sandbox Code Playgroud)
更进一步,我更确定ICacheProvider
使用plain object
s的具体实现工作,无论其具体类型如何.有了这个,您可以进一步简化合同:
public interface ICacheProvider
{
object Get(string key);
bool Set(string key, object value, TimeSpan expiration);
}
Run Code Online (Sandbox Code Playgroud)
以及一些扩展方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
现在,使用缓存的最常见操作之一是"获取或添加"行为,这可以表示为另一种方法ICacheProvider
:
object GetOrSet(string key, Func<object> valueProvider, TimeSpan expiration)
Run Code Online (Sandbox Code Playgroud)