[英]implement repository factory C#
我有一個使用以下代碼返回存儲庫的網站,它將接受一個接口並返回找到的第一個實現,但是,我認為代碼太慢並導致問題,是否有更好的方法來實現?
謝謝
public T For<T>() where T : class
{
T returnVar = null;
Assembly asm = Assembly.GetExecutingAssembly();
var types = asm.GetTypes().Where(x => x.IsClass == true && x.Namespace != null && x.Namespace.StartsWith("Website.Core.Data.Repositories"));
var result = types.Where(x => x.GetInterface(typeof(T).Name) != null);
foreach (var x in result)
{
var mi = x.GetConstructors();
returnVar = (T)asm.CreateInstance(x.UnderlyingSystemType.ToString());
}
if (returnVar != null)
return returnVar;
else
throw new Exception("No Repository for: " + typeof(T).Name);
}
一個明顯的優化方法是緩存每個類型T的結果(如果您每次都需要新實例,則緩存類型和構造函數信息)。
通過在程序集中查找來定位正確類型的結果在運行時不會改變。
另一方面,您最好使用IoC容器。
您為什么不嘗試使用DI容器呢? 即使沒有知識,Autofac之類的東西也應該很容易放入,並且在運行時執行方面要非常快(明顯的替代方法是Windsor甚至StructureMap。聽說過有關Ninject性能的內容,但是很久以前,還不確定Microsoft Unity,但可能沒有最好的速度之一)。
閱讀此頁上的代碼。 你會喜歡的 :)
http://code.google.com/p/autofac/wiki/掃描
這個怎么樣:
private readonly Dictionary<Type, object> _items = new Dictionary<Type, object>();
public T For<T>() where T : class
{
Type serviceType = typeof (T);
lock (_items)
{
object instance;
if (_items.TryGetValue(serviceType, out instance))
return (T) instance;
}
Assembly asm = Assembly.GetExecutingAssembly();
var types = asm.GetTypes().Where(x => x.IsClass
&& !x.IsAbstract
&& serviceType.IsAssignableFrom(x)
);
T returnVar = null;
foreach (Type x in types)
{
ConstructorInfo[] mi = x.GetConstructors();
returnVar = (T) asm.CreateInstance(x.UnderlyingSystemType.ToString());
}
if (returnVar != null)
{
lock (_items)
_items.Add(serviceType, returnVar);
return returnVar;
}
throw new Exception("No Repository for: " + typeof (T).Name);
}
我認為您在這里的建築物有點像臨時IOC容器。 訣竅是在您首次解析接口和類之后,保存接口和類之間的映射,這樣就不必每次都查找它。 因此,此類將需要狀態來提高性能。
但我可能會考慮閱讀IOC,並使用功能齊全的IOC容器(例如溫莎城堡或Unity)來解析這些映射。 我相信Windor Castle默認情況下會將您前面帶有I的接口解析為沒有它的類(IOrderProcessor-> OrderProcessor)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.