• TypeFinder学习


    不知道大家是如何查找反射程序集中的类型。Nop封装了一个不错的实现。

    接口ITypeFinder

    /// <summary>
        /// Classes implementing this interface provide information about types 
        /// to various services in the Nop engine.
        /// </summary>
        public interface ITypeFinder
        {
            IList<Assembly> GetAssemblies();
    
            IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, bool onlyConcreteClasses = true);
    
            IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true);
    
            IEnumerable<Type> FindClassesOfType<T>(bool onlyConcreteClasses = true);
    
            IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true);
    
            IEnumerable<Type> FindClassesOfType<T, TAssemblyAttribute>(bool onlyConcreteClasses = true) where TAssemblyAttribute : Attribute;
    
            IEnumerable<Assembly> FindAssembliesWithAttribute<T>();
    
            IEnumerable<Assembly> FindAssembliesWithAttribute<T>(IEnumerable<Assembly> assemblies);
    
            IEnumerable<Assembly> FindAssembliesWithAttribute<T>(DirectoryInfo assemblyPath);
    
    
        }

    Nop中的三个ITypeFinder实现类。

    1.FakeTypeFinder

    模拟额TypeFinder,通过构造器传递模拟需要查找的类型

    [Test]
            public void MyFakeTypeFinder()
            {
                var finder = new FakeTypeFinder(typeof(SomeClass));
    
                var type = finder.FindClassesOfType<ISomeInterface>();
                Assert.True(type.Any());
            }
    
            public interface ISomeInterface
            {
            }
    
            public class SomeClass : ISomeInterface
            {
            }

    2.AppDomainTypeFinder,在App或者单元测试中使用

    [Test]
            public void TypeFinder_Benchmark_Findings()
            {
                var finder = new AppDomainTypeFinder();
                var type = finder.FindClassesOfType<ISomeInterface>();
                type.Count().ShouldEqual(1);
                typeof(ISomeInterface).IsAssignableFrom(type.FirstOrDefault()).ShouldBeTrue();
            }

    3.WebAppTypeFinder

    继承自AppDomainTypeFinder。比AppDomainTypeFinder多支持了Web项目的类型查找

    那TypeFinder是如何工作的?

    1.FakeType(查找通过构造函数传递进来的types中的类型)

    public FakeTypeFinder(params Type[] types)
            {
                Assemblies = new Assembly[0];
                this.Types = types;
            }
            
     public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, bool onlyConcreteClasses = true)
            {
                return (from t in Types
                        where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true)
                        select t).ToList();
            }

    2.AppDomainTypeFinder(匹配循环程序集中的类)

    public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true)
            {
                var result = new List<Type>();
                try
                {
                    foreach (var a in assemblies)
                    {
                        foreach (var t in a.GetTypes())
                        {
                            if (assignTypeFrom.IsAssignableFrom(t) || (assignTypeFrom.IsGenericTypeDefinition && DoesTypeImplementOpenGeneric(t, assignTypeFrom)))
                            {
                                if (!t.IsInterface)
                                {
                                    if (onlyConcreteClasses)
                                    {
                                        if (t.IsClass && !t.IsAbstract)
                                        {
                                            result.Add(t);
                                        }
                                    }
                                    else
                                    {
                                        result.Add(t);
                                    }
                                }
                            }
                        }
    
                    }
                }
                catch (ReflectionTypeLoadException ex)
                {
                    var msg = string.Empty;
                    foreach (var e in ex.LoaderExceptions)
                        msg += e.Message + Environment.NewLine;
    
                    var fail = new Exception(msg, ex);
                    Debug.WriteLine(fail.Message, fail);
    
                    throw fail;
                }
                return result;
            }

    总结:TypeFinder提供了简便的接口来查找程序集中的类。我们也可以很方便的提取出来使用在自己的项目中。

  • 相关阅读:
    我要翻译《Think Python》- 004 第二章 变量, 表达式和语句
    我要翻译《Think Python》-003 第一章 编程之道
    我要翻译《Think Python》-002 贡献列表 & 目录部分
    我要翻译《Think Python》
    ORA-12514 解决方法
    好玩的东西
    sublime HtmlPrettify
    [转]bing壁纸天天换 初识shell魅力
    nginx+lua+redis 处理APK包替换
    算法整理
  • 原文地址:https://www.cnblogs.com/miku/p/2698869.html
Copyright © 2020-2023  润新知