WebApi 插件式构建方案:IOC 容器初始化

一般来说,一个现代化的网站加载流程是这样的:程序集加载后,我们会初始化 IOC 容器,以便于接下来解析对象用。

我们插件式的开发,这一步更为重要。这是因为在开发阶段,这些程序集以及 IOC 配置都是分属于多个解决方案的,在部署前很可能还没有连调。如何在集成在一起后,保证起码的可用性,是很关键的一个步骤。研究稍微深一点的同学,应该很清楚 WebApi 框架本身就集成了一个 IOC 框架用于对象的生成。我们要做的工作就是在此基础上扩展,把我们要额外注入的东西添加进去。

IOC 容器选型:Unity

选用 Unity 无可厚非,公司一直在用并且也没什么想换的意思。在第一篇文章里,@elder 说 MEF 不错,但是大环境下,确实没见过有人在用。包括微软自家的 MVC 和 WebApi,基本思想都是实现 CommonServiceLocation。如果有企业级的应用在使用 MEF,不妨通过私信告诉我。我也想看看这个集成在 .Net 4 中的微软亲儿子,到底是骡子还是马。

不管怎么说,多一种选择总是没错的。至于其它的 IOC 框架,从对 CommonServiceLocation 做适配上来看,基本上都是大同小异,只是获取类型注册的方式有所不同而已。

这里我选用现成的 Unity.WebApi 组件将 WebApi 自身的 IOC 容器扩展到 Unity 中(反编译后可以发现就两个类,直接把代码拷贝出来,贴到项目里也是可以的)。

容器注册项加载约定

对于一个 IOC 容器来说,通过配置文件加载注册项都是不可或缺的。连 Ninject 这种奇葩,都有第三方对其扩展了配置文件支持。在编程中,我个人特别讨厌不想干的代码侵入,所以一般我会把 IOC 的注入写在配置文件中:一方面代码干净了,另一方面,一个简单的配置修改,就可以不用重新编译代码了,这不就是 IOC 的本质吗?

配置文件可以多次附加配置到一个 IOC 容器实例上很必要,这样我就可以连续把多个配置文件的注册项添加到一个实例上。事实上,IOC 容器的实例,全局有且只有一个的时候才有用。回到咱们的 Unity 上面,很不幸的是,Unity 支持这个要求,呵呵。

额外的,为了项目整体上一致,我为 Unity 的配置文件约定:

  • Unity 配置文件名称为 unity.config
  • 存放路径为:相对当前程序集所在目录的 Configuration\unity.config,这样只需要调整生成时总是复制就可以了。

注:这里如果你想灵活一些,可以在上一节的配置文件中添加你的 Unity 配置文件路径设置信息。

部分源代码:自然语义

额外的,在 Global 中需要用 Unity.WebApi 把扩展点挂接上。下面是 IOC 加载各个模块配置的事情代码:

public interface IContainerConfiguration
{
object Config(object container);
} public class DefaultContainerConfiguration : IContainerConfiguration
{
public object Config(object container)
{
var data = new List<string>(); data.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configuration\\unity.config")); foreach(var item in DynamicModule.Instance.Modules)
{
data.Add(Path.Combine(item.BaseDirectory, "Configuration\\unity.config"));
}
}
}

补充:程序集加载

上一节写完以后,有人私信问我加载顺序的问题。在这里补充一下,程序集的加载和顺序是无关的:我可以先加载接口的实现程序集,再加载接口程序集。但是还有一些需要注意的地方:

  • 程序集加载时,首先加载的程序集 B 如果引用了后续加载的程序集 A,加载不会产生错误。
  • 后续被引用的程序集 A 被加载后,先前加载的程序集 B 中的类型就可以正常访问了。
  • 在后续程序集 A 加载之前,如果有使用 B 中的程序集,就会提示出错;后续程序集 A 加载后,这个错误仍将继续存在,且一直存在。

所有正确的做法是:程序集加载可以无序进行,但是一定要加载全部程序集后,再进行后续操作。

 
 
标签: IOCWebApi

IOC 容器初始化的更多相关文章

  1. Spring IoC容器初始化过程学习

    IoC容器是什么?IoC文英全称Inversion of Control,即控制反转,我么可以这么理解IoC容器: 把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为I ...

  2. spring源码学习之路---深度分析IOC容器初始化过程(四)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近由于工作和生活,学习耽搁 ...

  3. spring源码 — 一、IoC容器初始化

    IoC容器初始化 注意:本次的spring源码是基于3.1.1.release版本 容器:具有获取Bean功能--这是最基本功能,也是BeanFactory接口定义的主要行为,在添加了对于资源的支持之 ...

  4. 挖坟之Spring.NET IOC容器初始化

    因查找ht项目中一个久未解决spring内部异常,翻了一段时间源码.以此文总结springIOC,容器初始化过程. 语言背景是C#.网上有一些基于java的spring源码分析文档,大而乱,乱而不全, ...

  5. 【spring源码分析】IOC容器初始化(总结)

    前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...

  6. 【spring源码分析】IOC容器初始化(一)

    前言:spring主要就是对bean进行管理,因此IOC容器的初始化过程非常重要,搞清楚其原理不管在实际生产或面试过程中都十分的有用.在[spring源码分析]准备工作中已经搭建好spring的环境, ...

  7. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

  8. 【spring源码分析】IOC容器初始化(三)

    前言:在[spring源码分析]IOC容器初始化(二)中已经得到了XML配置文件的Document实例,下面分析bean的注册过程. XmlBeanDefinitionReader#registerB ...

  9. 【spring源码分析】IOC容器初始化(四)

    前言:在[spring源码分析]IOC容器初始化(三)中已经分析了BeanDefinition注册之前的一些准备工作,下面将进入BeanDefinition注册的核心流程. //DefaultBean ...

随机推荐

  1. NUnit3 Test Adapter vs2015

    NUnit的安装 前言:NUnit是什么? NUnit 是一个单元测试框架,专门针对于.NET来写的.NUnit是xUnit家族种的第4个主打产品,完全由C#语言来编写,并且编写时充分利用了许多.NE ...

  2. 采用Flume实时采集和处理数据

    它已成功安装Flume在...的基础上.本文将总结使用Flume实时采集和处理数据,详细过程,如下面: 第一步,在$FLUME_HOME/conf文件夹下,编写Flume的配置文件,命名为flume_ ...

  3. C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】

    STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...

  4. Bootstrap(2)整体架构

    Bootstrap(2)整体架构 大多数Bootstrap的使用者都认为Bootstrap只提供了CSS组件 和JavaScript插件,其实CSS组件和JavaScript插件只是Bootstrap ...

  5. 数组、链表、Hash(转)

    在程序中,存放指定的数据最常用的数据结构有两种:数组和链表. 数组和链表的区别: 1.数组是将元素在内存中连续存放. 链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起. 2.数组 ...

  6. Ohloh研究报告

    1.底       由于近期接合ospaf同样是一个开源项目的成熟度分析工具,由于该项目现在Ohloh我们有共同的东西,这么ohloh我们进行了调查.       简单的说,初始ohloh是一个代码搜 ...

  7. iOS学习 plist读取和写入文件

    干iOS开发时间.后经常用来plist文件,  那plist什么文件是它? 它的全称是:Property List.属性列表文件.它是一种用来存储串行化后的对象的文件.属性列表文件的扩展名为.plis ...

  8. 一Flash从入门开发者放弃了成长之路

    本文将依照入门.成长.转行三个关键词来讲述作者这些年使用Flash进行项目开发的整个历史过程. 一.入门--開始走上Flash的道路. 和Flash的机缘要从大学时代说起.2005年下半年.学校开设了 ...

  9. thinkphp学习笔记2—入口文件

    原文:thinkphp学习笔记2-入口文件 在thinkphp中有两个入口文件,一个是项目的入口文件,是index.php在主目录里面,还有一个是thinkphp框架的的入口文件,放在框架目录下面如: ...

  10. 用java字节码解释i++和++i(转)

    这几天抽着一些时间,把Java的class文件结构研究了一下,再后来就想起了这个令人厌烦的问题,想从字节码指令的角度看看,java到底是怎么处理这个的 先看一段java代码 package bishi ...