NopCommerce为了支持插件功能,以及支持一些自动注册的功能。系统提供了类型查找器。ITypeFinder以及实现类就是提供此功能。通过类型查找器可以查找本程序域中的类,也可以查找整个bin目录下所有动态链接库中类,并把它们注册到类型反转容器中。ITypeFinder以及实现类如下:

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

FakeTypeFinder(模拟类型查找器)

 /// <summary>/// 模拟类型查找/// </summary>public class FakeTypeFinder : ITypeFinder{public Assembly[] Assemblies { get; set; }public Type[] Types { get; set; }public FakeTypeFinder(Assembly assembly, params Type[] types){Assemblies = new[] { assembly };this.Types = types;}public FakeTypeFinder(params Type[] types){Assemblies = new Assembly[0];this.Types = types;}public FakeTypeFinder(params Assembly[] assemblies){this.Assemblies = assemblies;}public IList<Assembly> GetAssemblies(){return Assemblies.ToList();}public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, bool onlyConcreteClasses = true){return (from t in Typeswhere !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true)select t).ToList();}public IEnumerable<Type> FindClassesOfType<T>(bool onlyConcreteClasses = true){return FindClassesOfType(typeof(T), onlyConcreteClasses);}public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true){return FindClassesOfType(assignTypeFrom, onlyConcreteClasses);}public IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true){return FindClassesOfType(typeof(T), onlyConcreteClasses);}}

View Code

 #region FakeTypeFinder[TestMethod]public void FakeTypeFinderTest(){var finder = new FakeTypeFinder(typeof(FakeClass));var type = finder.FindClassesOfType<IFakeInterface>();Assert.IsTrue(type.Any());}public interface IFakeInterface{}public class FakeClass : IFakeInterface{}#endregion

AppDomainTypeFinder(应用程序类型查找器)

/// <summary>/// A class that finds types needed by Nop by looping assemblies in the /// currently executing AppDomain. Only assemblies whose names matches/// certain patterns are investigated and an optional list of assemblies/// referenced by <see cref="AssemblyNames"/> are always investigated./// </summary>public class AppDomainTypeFinder : ITypeFinder{#region Fieldsprivate bool ignoreReflectionErrors = true;private bool loadAppDomainAssemblies = true;private string assemblySkipLoadingPattern = "^System|^mscorlib|^Microsoft|^AjaxControlToolkit|^Antlr3|^Autofac|^AutoMapper|^Castle|^ComponentArt|^CppCodeProvider|^DotNetOpenAuth|^EntityFramework|^EPPlus|^FluentValidation|^ImageResizer|^itextsharp|^log4net|^MaxMind|^MbUnit|^MiniProfiler|^Mono.Math|^MvcContrib|^Newtonsoft|^NHibernate|^nunit|^Org.Mentalis|^PerlRegex|^QuickGraph|^Recaptcha|^Remotion|^RestSharp|^Rhino|^Telerik|^Iesi|^TestDriven|^TestFu|^UserAgentStringLibrary|^VJSharpCodeProvider|^WebActivator|^WebDev|^WebGrease";private string assemblyRestrictToLoadingPattern = ".*";private IList<string> assemblyNames = new List<string>();#endregion#region Properties/// <summary>The app domain to look for types in.</summary>public virtual AppDomain App{get { return AppDomain.CurrentDomain; }}/// <summary>Gets or sets wether Nop should iterate assemblies in the app domain when loading Nop types. Loading patterns are applied when loading these assemblies.</summary>public bool LoadAppDomainAssemblies{get { return loadAppDomainAssemblies; }set { loadAppDomainAssemblies = value; }}/// <summary>Gets or sets assemblies loaded a startup in addition to those loaded in the AppDomain.</summary>public IList<string> AssemblyNames{get { return assemblyNames; }set { assemblyNames = value; }}/// <summary>Gets the pattern for dlls that we know don't need to be investigated.</summary>public string AssemblySkipLoadingPattern{get { return assemblySkipLoadingPattern; }set { assemblySkipLoadingPattern = value; }}/// <summary>Gets or sets the pattern for dll that will be investigated. For ease of use this defaults to match all but to increase performance you might want to configure a pattern that includes assemblies and your own.</summary>/// <remarks>If you change this so that Nop assemblies arn't investigated (e.g. by not including something like "^Nop|..." you may break core functionality.</remarks>public string AssemblyRestrictToLoadingPattern{get { return assemblyRestrictToLoadingPattern; }set { assemblyRestrictToLoadingPattern = value; }}#endregion#region Methodspublic IEnumerable<Type> FindClassesOfType<T>(bool onlyConcreteClasses = true){return FindClassesOfType(typeof(T), onlyConcreteClasses);}public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, bool onlyConcreteClasses = true){return FindClassesOfType(assignTypeFrom, GetAssemblies(), onlyConcreteClasses);}public IEnumerable<Type> FindClassesOfType<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true){return FindClassesOfType(typeof (T), assemblies, onlyConcreteClasses);}public IEnumerable<Type> FindClassesOfType(Type assignTypeFrom, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses = true){var result = new List<Type>();try{foreach (var a in assemblies){Type[] types = null;try{types = a.GetTypes();}catch{//Entity Framework 6 doesn't allow getting types (throws an exception)if (!ignoreReflectionErrors){throw;}}if (types != null){foreach (var t in types){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;}/// <summary>Gets the assemblies related to the current implementation.</summary>/// <returns>A list of assemblies that should be loaded by the Nop factory.</returns>public virtual IList<Assembly> GetAssemblies(){var addedAssemblyNames = new List<string>();var assemblies = new List<Assembly>();if (LoadAppDomainAssemblies)AddAssembliesInAppDomain(addedAssemblyNames, assemblies);AddConfiguredAssemblies(addedAssemblyNames, assemblies);return assemblies;}#endregion#region Utilities/// <summary>/// Iterates all assemblies in the AppDomain and if it's name matches the configured patterns add it to our list./// </summary>/// <param name="addedAssemblyNames"></param>/// <param name="assemblies"></param>private void AddAssembliesInAppDomain(List<string> addedAssemblyNames, List<Assembly> assemblies){foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()){if (Matches(assembly.FullName)){if (!addedAssemblyNames.Contains(assembly.FullName)){assemblies.Add(assembly);addedAssemblyNames.Add(assembly.FullName);}}}}/// <summary>/// Adds specificly configured assemblies./// </summary>/// <param name="addedAssemblyNames"></param>/// <param name="assemblies"></param>protected virtual void AddConfiguredAssemblies(List<string> addedAssemblyNames, List<Assembly> assemblies){foreach (string assemblyName in AssemblyNames){Assembly assembly = Assembly.Load(assemblyName);if (!addedAssemblyNames.Contains(assembly.FullName)){assemblies.Add(assembly);addedAssemblyNames.Add(assembly.FullName);}}}/// <summary>/// Check if a dll is one of the shipped dlls that we know don't need to be investigated./// </summary>/// <param name="assemblyFullName">/// The name of the assembly to check./// </param>/// <returns>/// True if the assembly should be loaded into Nop./// </returns>public virtual bool Matches(string assemblyFullName){return !Matches(assemblyFullName, AssemblySkipLoadingPattern)&& Matches(assemblyFullName, AssemblyRestrictToLoadingPattern);}/// <summary>/// Check if a dll is one of the shipped dlls that we know don't need to be investigated./// </summary>/// <param name="assemblyFullName">/// The assembly name to match./// </param>/// <param name="pattern">/// The regular expression pattern to match against the assembly name./// </param>/// <returns>/// True if the pattern matches the assembly name./// </returns>protected virtual bool Matches(string assemblyFullName, string pattern){return Regex.IsMatch(assemblyFullName, pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);}/// <summary>/// Makes sure matching assemblies in the supplied folder are loaded in the app domain./// </summary>/// <param name="directoryPath">/// The physical path to a directory containing dlls to load in the app domain./// </param>protected virtual void LoadMatchingAssemblies(string directoryPath){var loadedAssemblyNames = new List<string>();foreach (Assembly a in GetAssemblies()){loadedAssemblyNames.Add(a.FullName);}if (!Directory.Exists(directoryPath)){return;}foreach (string dllPath in Directory.GetFiles(directoryPath, "*.dll")){try{var an = AssemblyName.GetAssemblyName(dllPath);if (Matches(an.FullName) && !loadedAssemblyNames.Contains(an.FullName)){App.Load(an);}//old loading stuff//Assembly a = Assembly.ReflectionOnlyLoadFrom(dllPath);//if (Matches(a.FullName) && !loadedAssemblyNames.Contains(a.FullName))//{//    App.Load(a.FullName);//}
                }catch (BadImageFormatException ex){Trace.TraceError(ex.ToString());}}}/// <summary>/// Does type implement generic?/// </summary>/// <param name="type"></param>/// <param name="openGeneric"></param>/// <returns></returns>protected virtual bool DoesTypeImplementOpenGeneric(Type type, Type openGeneric){try{var genericTypeDefinition = openGeneric.GetGenericTypeDefinition();foreach (var implementedInterface in type.FindInterfaces((objType, objCriteria) => true, null)){if (!implementedInterface.IsGenericType)continue;var isMatch = genericTypeDefinition.IsAssignableFrom(implementedInterface.GetGenericTypeDefinition());return isMatch;}return false;}catch{return false;}}#endregion}

View Code

 #region AppDomainTypeFinderpublic void AppDomainTypeFinderTest(){var finder = new AppDomainTypeFinder();var type = finder.FindClassesOfType<IAppDomainInterface>();type.Count();typeof(IAppDomainInterface).IsAssignableFrom(type.FirstOrDefault());}public interface IAppDomainInterface{}public class AppDomainClass : IAppDomainInterface{}#endregion

在App或者单元测试中使用

WebAppTypeFinder(Web应用程序类型查找器)

/// <summary>/// Provides information about types in the current web application. /// Optionally this class can look at all assemblies in the bin folder./// </summary>public class WebAppTypeFinder : AppDomainTypeFinder{#region Fieldsprivate bool _ensureBinFolderAssembliesLoaded = true;private bool _binFolderAssembliesLoaded;#endregion#region Ctorpublic WebAppTypeFinder(NopConfig config){this._ensureBinFolderAssembliesLoaded = config.DynamicDiscovery;}#endregion#region Properties/// <summary>/// Gets or sets wether assemblies in the bin folder of the web application should be specificly checked for beeing loaded on application load. This is need in situations where plugins need to be loaded in the AppDomain after the application been reloaded./// </summary>public bool EnsureBinFolderAssembliesLoaded{get { return _ensureBinFolderAssembliesLoaded; }set { _ensureBinFolderAssembliesLoaded = value; }}#endregion#region Methods/// <summary>/// Gets a physical disk path of \Bin directory/// </summary>/// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>public virtual string GetBinDirectory(){if (HostingEnvironment.IsHosted){//hostedreturn HttpRuntime.BinDirectory;}//not hosted. For example, run either in unit testsreturn AppDomain.CurrentDomain.BaseDirectory;}public override IList<Assembly> GetAssemblies(){if (this.EnsureBinFolderAssembliesLoaded && !_binFolderAssembliesLoaded){_binFolderAssembliesLoaded = true;string binPath = GetBinDirectory();//binPath = _webHelper.MapPath("~/bin");
                LoadMatchingAssemblies(binPath);}return base.GetAssemblies();}#endregion}

View Code

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

WebAppTypeFinder 这个类就可以对网站下面BIN文件夹所有的DLL文件进行反射查找程序集,可以根据类型 也可以跟特性查找,总之性能不错,大家可以拷贝代码 进行测试

http://www.cnblogs.com/miku/archive/2012/09/24/2700776.html

http://www.cnblogs.com/flyfish2012/p/3779810.html

转载于:https://www.cnblogs.com/xchit/p/4674133.html

类型查找器 ITypeFinder相关推荐

  1. 《Hack与HHVM权威指南》——1.1 为什么使用类型检查器

    本节书摘来自华章出版社<Hack与HHVM权威指南>一书中的第1章,第1.1节,作者 Owen Yamauchi,更多章节内容可以访问云栖社区"华章计算机"公众号查看. ...

  2. Elasticsearch(一)——Es安装(三个必安工具、安装各种类型分词器)、Es 十大核心概念、通过 Kibana 操作 Es(中文分词、Es各种索引命令操作)

    Elasticsearch(一)--Es安装(三个必安工具.安装各种类型分词器).Es 十大核心概念.通过 Kibana 操作 Es(中文分词.Es各种索引命令操作) 一.Elasticsearch ...

  3. 【Android 属性动画】属性动画 Property Animation 工作原理 ( 线性插值动画 | 非线性插值动画 | 动画计算 | 经过分数 | 插值分数 | 类型估值器)

    文章目录 一.线性插值动画示例 二.非线性插值动画示例 三.动画计算方式 四.时间经过分数 ( Elapsed Fraction ) 五.插值分数 ( Interpolated Fraction ) ...

  4. php搜索文件名,php实现按文件名搜索文件的远程文件查找器

    对于本地,我们可以利用windows自带的查找去进行查找,但是对于线上的话,如查找ftp空间里面文件,本程序是很有用的. 使用效果: php文件查找器源码: . 代码如下: php版文件查找(file ...

  5. 刚刚开源的Python静态类型检查器:Pyright

    近日,开发者msfterictraut在GitHub上提交了一个名为Pyrignt的开源项目,这是一个Python的静态类型检查器,主要是为了解决mypy等现有的Python类型检查器无法解决的问题. ...

  6. ora-00955: 名称已由现有对象使用_ai使用路径的方法是什么?ai怎么使用路径查找器?...

    Illustrator路径使用教程: 1.使用铅笔或画笔工具重塑路径 您也可以重塑路径.为此,通过单击"铅笔"工具来选择其形状,以重塑没有画笔笔触的路径.如果具有笔触,请选择&qu ...

  7. python mac读取 文件属性_从Python获取和设置mac文件和文件夹查找器标签

    macfile模块是^{}模块的一部分,在"2006-11-20 0.2.0"中被重命名为mactypes 使用此模块,以下两个函数可用于获取和设置appscript 1.0版的查 ...

  8. 中路径查找器的功能_还在用路径查找器?试试它吧!

    本周马克笔设计留学的安老师想要和大家继续分享关于Illustrator中的小技巧,这次要跟大家推荐的是一个叫做"Shape Builder Tool"(形状生成器)的工具.这是一个 ...

  9. 检查python模块_Python输入模块–有效使用类型检查器

    检查python模块 Introduced since Python 3.5, Python's typing module attempts to provide a way of hinting ...

  10. 自制Unity文件查找器,支持拼音搜索

    前言 一个大型项目,配置表上千个是很正常的,这个时候想要搜索某个配置表,是有点蛋疼的事情. 自己写个配置查找器吧,效果如下: 优点: 搜索速度快: 支持拼音搜索: 支持快速打开: 缺点: 拼音只能挨个 ...

最新文章

  1. 单片机会被淘汰吗?单片机现在还有用吗?
  2. Flex/Flash Builder里实用但被忽略的编译参数
  3. php call_user_func和,php – call_user_func()和$var()之间有区别吗?
  4. 如何使用Maven scope
  5. 数据结构与算法--图论-深度优先搜索及其应用
  6. 【C++grammar】文件I/O流的基本用法
  7. 调试nodejs项目接口,使用Posman,用req.body拿不到数据
  8. windows配置samba客户端_怎样设置Samba文件服务器以使用Windows客户端
  9. mysql两个查询结果差集_【Mysql】求两个表(查询结果)的差集
  10. matlab如何矩阵相除,Matlab中的矩阵除法有问题???
  11. mysql获取当月数据_Python + MySQL如何获取股票数据(历史数据)
  12. Uva 247 - Calling Circles(传递闭包 / 强连通分量)
  13. 怎么去除三角下拉_用什么方法可以有效去除外墙涂料?
  14. java获取当前日期和时间的二种方法分享
  15. .NET Framework 3.5 sp1离线安装方案
  16. 10行代码带你入门Windows编程
  17. java的代码大全_java代码大全
  18. 求证:拉皮手术费多少钱,拉皮手术后会有哪些后遗症,原来如此
  19. 苹果手机温度测试软件,苹果手机测温神器上线啦!
  20. 食堂配送公司订餐微信小程序开发制作定制功能需求文档

热门文章

  1. 中芯国际三季度营业收入创新高;德州仪器与德赛西威签署合作备忘录 | 全球TMT...
  2. qq围棋 android,腾讯围棋(QQ围棋)
  3. 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
  4. linux nfs性能差,linux – 奇怪的nfs性能:1个线程比8个好,8个好于2个!
  5. 嵌入式linux dlna,DLNA 编译
  6. 为什么它有典型FaaS能力,却是非典型FaaS架构?
  7. 鲲志说:向我跌宕起伏,喜忧参半的2022致敬!
  8. Xshell脚本实现自动登陆||自动登陆的几种方式。
  9. Java导入Excel文档到数据库
  10. vmware虚拟机序列号