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提供了简便的接口来查找程序集中的类。我们也可以很方便的提取出来使用在自己的项目中。

你可能感兴趣的:(find)