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