简体   繁体   English

实施仓库工厂C#

[英]implement repository factory C#

I have a website that is using the following code to return a repository, it will accept an interface and return the firt implementation it finds, however, I think the code is too slow and causing issues, is there any better ways to implement this? 我有一个使用以下代码返回存储库的网站,它将接受一个接口并返回找到的第一个实现,但是,我认为代码太慢并导致问题,是否有更好的方法来实现?

Thanks 谢谢

 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);        
    }

An obvious optimization would be to cache the result of each type T (if you want new instances each time, then cache the type and constructor info). 一个明显的优化方法是缓存每个类型T的结果(如果您每次都需要新实例,则缓存类型和构造函数信息)。

The result of locating the correct type by looking in the assembly is not going to change at runtime. 通过在程序集中查找来定位正确类型的结果在运行时不会改变。

On another note you might be better off using an IoC container for this. 另一方面,您最好使用IoC容器。

Why didn't you try to use a DI container instead? 您为什么不尝试使用DI容器呢? Something like Autofac should be fairly easy to put in even without knowledge and pretty fast in terms of runtime excution (obvious alternatives are Windsor and maybe StructureMap. Heard stuff about Ninject performance but it was long time ago, not sure about Microsoft Unity but likely not one of the best for speed). 即使没有知识,Autofac之类的东西也应该很容易放入,并且在运行时执行方面要非常快(明显的替代方法是Windsor甚至StructureMap。听说过有关Ninject性能的内容,但是很久以前,还不确定Microsoft Unity,但可能没有最好的速度之一)。

Read the code on this page. 阅读此页上的代码。 You'll like it :) 你会喜欢的 :)
http://code.google.com/p/autofac/wiki/Scanning http://code.google.com/p/autofac/wiki/扫描

How about this: 这个怎么样:

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);
    }

I think what your building here is sort of a makeshift IOC container. 我认为您在这里的建筑物有点像临时IOC容器。 The trick is saving the mapping between the interface and the class after you first resolve it so that you dont have to look it up every time. 诀窍是在您首次解析接口和类之后,保存接口和类之间的映射,这样就不必每次都查找它。 So this class will need state to improve performance. 因此,此类将需要状态来提高性能。

But i might consider reading up on IOC and using a fully functional IOC container such as Windsor Castle or Unity to resolve these mappings. 但我可能会考虑阅读IOC,并使用功能齐全的IOC容器(例如温莎城堡或Unity)来解析这些映射。 I believe Windor Castle will by default resolve your interfaces that have an I in front of them to classes without it (IOrderProcessor -> OrderProcessor). 我相信Windor Castle默认情况下会将您前面带有I的接口解析为没有它的类(IOrderProcessor-> OrderProcessor)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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