[英]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.