学习kooboo的框架发现它的注入容器方法比较特别,同样是利用MVC的注入点,但它是查找网站下面bin所有的DLL利用反射查找特性找到对应的服务注入到容器。

这样的好处很简单:完全可以不用关心IOC容器是Ninject还是autofac 或者其它什么容器。 只要写上特性标记,再把对应的DLL拷贝到BIN下面,网站一启动就会自动注入到容器中。彻底进行解耦。

它的IOC注入步骤先后顺序:

1.程序集反射查找

2.IOC容器引擎初始化

3.利用特性注入IOC容器

4.MVC注入点注入

因为本人比较笨,理解东西比较差强人意,所以将以7篇文章分别介绍各个模块加强自己的理解:

IOC容器特性注入第一篇:程序集反射查找

IOC容器特性注入第二篇:初始引擎查找对应的IOC容器

IOC容器特性注入第三篇:Attribute封装

IOC容器特性注入第四篇:容器初始化

IOC容器特性注入第五篇:查找(Attribute)特性注入

IOC容器特性注入第六篇:利用MVC注入点,把容器启动

IOC容器特性注入第七篇:请求上下文作用域

源代码,我放在最后一篇,大家可以去下载。

我首先介绍下如何对网站BIN下面的DLL进行反射查找:

kooboo的程序集反射查找类就是Nop的三个封装类,分别是:

1.接口(ITypeFinder):

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

2.应用程序实现类(AppDomainTypeFinder):

public class AppDomainTypeFinder : ITypeFinder {#region Private Fieldsprivate bool loadAppDomainAssemblies = true;private string assemblySkipLoadingPattern = "^System|^mscorlib|^Microsoft|^CppCodeProvider|^VJSharpCodeProvider|^WebDev|^Castle|^Iesi|^log4net|^NHibernate|^nunit|^TestDriven|^MbUnit|^Rhino|^QuickGraph|^TestFu|^Telerik|^ComponentArt|^MvcContrib|^AjaxControlToolkit|^Antlr3|^Remotion|^Recaptcha|^DotNetOpenAuth,";private string assemblyRestrictToLoadingPattern = ".*";private IList<string> assemblyNames = new List<string>();#endregion#region Constructors/// <summary>Creates a new instance of the AppDomainTypeFinder.</summary>public AppDomainTypeFinder() {}#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 app should iterate assemblies in the app domain when loading 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 assemblies arn't investigated (e.g. by not including something like "^MTA|..." you may break core functionality.</remarks>public string AssemblyRestrictToLoadingPattern {get { return assemblyRestrictToLoadingPattern; }set { assemblyRestrictToLoadingPattern = value; }}#endregion#region Internal Attributed Assembly classprivate class AttributedAssembly {internal Assembly Assembly { get; set; }internal Type PluginAttributeType { get; set; }}#endregion#region ITypeFinderpublic 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) {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;}public IEnumerable<Type> FindClassesOfType<T, TAssemblyAttribute>(bool onlyConcreteClasses = true) where TAssemblyAttribute : Attribute {var found = FindAssembliesWithAttribute<TAssemblyAttribute>();return FindClassesOfType<T>(found, onlyConcreteClasses);}public IEnumerable<Assembly> FindAssembliesWithAttribute<T>() {return FindAssembliesWithAttribute<T>(GetAssemblies());}/// <summary>/// Caches attributed assembly information so they don't have to be re-read/// </summary>private readonly List<AttributedAssembly> _attributedAssemblies = new List<AttributedAssembly>();/// <summary>/// Caches the assembly attributes that have been searched for/// </summary>private readonly List<Type> _assemblyAttributesSearched = new List<Type>();public IEnumerable<Assembly> FindAssembliesWithAttribute<T>(IEnumerable<Assembly> assemblies) {//check if we've already searched this assembly);)if (!_assemblyAttributesSearched.Contains(typeof(T))) {var foundAssemblies = (from assembly in assemblieslet customAttributes = assembly.GetCustomAttributes(typeof(T), false)where customAttributes.Any()select assembly).ToList();//now update the cache_assemblyAttributesSearched.Add(typeof(T));foreach (var a in foundAssemblies) {_attributedAssemblies.Add(new AttributedAssembly { Assembly = a, PluginAttributeType = typeof(T) });}}//We must do a ToList() here because it is required to be serializable when using other app domains.return _attributedAssemblies.Where(x => x.PluginAttributeType.Equals(typeof(T))).Select(x => x.Assembly).ToList();}public IEnumerable<Assembly> FindAssembliesWithAttribute<T>(DirectoryInfo assemblyPath) {var assemblies = (from f in Directory.GetFiles(assemblyPath.FullName, "*.dll")select Assembly.LoadFrom(f)into assemblylet customAttributes = assembly.GetCustomAttributes(typeof(T), false)where customAttributes.Any()select assembly).ToList();return FindAssembliesWithAttribute<T>(assemblies);}/// <summary>Gets tne assemblies related to the current implementation.</summary>/// <returns>A list of assemblies that should be loaded by the 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/// <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>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 app.</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());}}}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;}}}

3.web应用程序继承App作用域类(WebAppTypeFinder):

public class WebAppTypeFinder : AppDomainTypeFinder {#region Fieldsprivate bool _ensureBinFolderAssembliesLoaded = true;private bool _binFolderAssembliesLoaded = false;#endregion#region Ctorpublic WebAppTypeFinder() {this._ensureBinFolderAssembliesLoaded = true;}#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;} else {//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}

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

下一篇:

IOC容器特性注入第二篇:初始引擎查找对应的IOC容器

转载于:https://www.cnblogs.com/flyfish2012/p/3779810.html

IOC容器特性注入第一篇:程序集反射查找相关推荐

  1. IOC容器特性注入第五篇:查找(Attribute)特性注入

    前面几篇文章分别介绍:程序集反射查找,特性,容器,但它们之间贯穿起来,形成查找Attribute注入IOC容器,就得需要下面这个类帮忙: 1.DependencyAttributeRegistrato ...

  2. IOC容器特性注入第四篇:容器初始化

    IOC容器,就是把各种服务都注入到容器里,想要什么就去拿什么,不仅解决服务类和接口类的耦合度还可以提高性能方便管理. 这里封装一个接口类和一个实现类 1.IContainerManager接口 pub ...

  3. IOC容器特性注入第六篇:利用MVC注入点,把容器启动

    这里是利用MVC三个注入点中的:IDependencyResolver 进行注入 在全局类中Global.asax代码如下: #region MVC InjectSystem.Web.Mvc.Depe ...

  4. Spring IOC容器组件注入的几种方式

    整理一下之前Spring的学习笔记,大致有一下几种Spring注入到容器中的方法: 1).配置在xml的方式. 2).开启包扫描@ComponentScan使用@Component,@Service, ...

  5. 大白话聊框架设计(入门篇) | 第四章:简单实现IOC容器

    文章目录 **1.简单实现IOC容器** **2.简单介绍IOC容器** **3.创建Inject注解** **4.创建IocContrainer** **5.初始化IOC容器** **6.改造原有N ...

  6. 控制反转IOC与依赖注入DI

    为什么80%的码农都做不了架构师?>>>    1. IoC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最 ...

  7. 【Spring学习】IOC容器

    1.IOC的理论背景 我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑. 图1 软件系统中耦合的对象 如果我们打开机械式手表的后盖,就 ...

  8. Spring IoC容器与Bean管理

    Spring IoC容器与Bean管理 一.Spring IoC容器与Bean管理 1.Spring快速入门 IoC控制反转 DI依赖注入 Spring概述 Spring IoC初体验 使用XML方式 ...

  9. 控制反转IOC、依赖注入DI的详细说明与举例

    文章目录 引入 IOC介绍 IOC的实现 通过构造函数注入依赖 通过 setter 设值方法注入依赖 依赖注入容器 IOC优缺点 优点 缺点 阅读时忽略语言差异,参考了很多其他博主内容,参考博文在最后 ...

最新文章

  1. 世界上最百变的人不是女友,竟然是......
  2. 【转】PHP date(Y-m-d H:i:s);获取当前时间 差8小时解决办法
  3. spark之CF协同过滤
  4. Windows 7中的远程桌面增强(Graphics Remoting, Remote Desktop)
  5. 两个vlan如何互通_网络交换机VLAN的常识与划分方法,你知道吗?
  6. GNU make manual 翻译( 一百八十二)
  7. 使用MySQL管理工具-SQLyog9.63报错号码2003,超详细解析
  8. 斯坦福发布AI年度报告,中国AI论文数全球第二,第一也不是美国【附下载】
  9. SparkMLlib之二Basic Stastics
  10. 航拍深圳湾体育中心全景
  11. insert的语句的三种方式
  12. python计算球体体积_用于计算python中的体积或表面积的良好算法
  13. 以太坊实战-attach命令
  14. 是时候来一发炸裂的开场了!
  15. 【C语言】初识C语言(中篇)
  16. python处理excel 隐藏sheet
  17. 2019.3.9 提高B组 T1 JZOJ 4742 单峰
  18. word2013 无法撤销解决方法-有效
  19. (九十)第六章复习题
  20. python5 5的 阵列_Biopython表型微阵列

热门文章

  1. JZOJ 6030. 【GDOI2019模拟2019.2.25】白白的
  2. hdu3068 . 最长回文
  3. 页面放在哪_seo页面怎么优化?seo页面优化有哪些方法?
  4. mysql数据丢失_当数据被误删除/误操作后造成数据丢失。你尝试过用什么手段来挽救数据/损失?...
  5. php crypt加密 盐值,PHP crypt()函数的用法讲解
  6. python的类与模块_Python类与模块属性
  7. nohup 带参数_广州市西门子两通阀VVF42.40-25C+SKD62带断电
  8. 聚类分析(Clustering Analysis)
  9. uvalive5096(积分题)
  10. JZOJ__Day 3:【NOIP普及模拟】排序(sort)