繁体   English   中英

实施仓库工厂C#

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM