NopCommerce架构分析(一)Autofac依赖注入类生成容器
nopcommerce为了实现松耦合的框架设计目的,使用了ioc框架:autofac。据有人测试,autofac是性能很好的ioc工具。
1、在ioc中,组件首先需要在ioc中注册,有通过配置文件注册的。像spring.net,也有通过特性注册的,像structuremap,也有通过代理来注册的,像autofac。但是ioc讲究一个原则,就是接口和实现分离。所有ioc就是生命某个具体类实现了某个接口。然后在使用时,系统从ioc中获取接口的实现类,并创建对象。
2、下面来看nopcommerce如何使用autofac实现松耦合的框架设计的。其实它的插件机制也是通过autofac来实现的。
ioc的封装及灵活使用机制主要在nop.core.infrastructure中封装的。在autofac中,对象又称为组件。组件生命周期分为:单例、临时和生命周期域内,如下定义:
namespace nop.core.infrastructure.dependencymanagement { public enum componentlifestyle { singleton = 0, transient = 1, lifetimescope = 2 } }
autofac中有容器、并提供方法注册接口及其类型,还提供方法查找到注册的类型,以及自动创建对象。
3、类型查找器
为了支持插件功能,以及支持一些自动注册的功能。系统提供了类型查找器。itypefinder以及实现类就是提供此功能。通过类型查找器可以查找本程序域中的类,也可以查找整个bin目录下所有动态链接库中类,并把它们注册到类型反转容器中。itypefinder以及实现类如下:
4、类型注册
容器管理类:containermanager,管理通过autofac生成的容器;
容器配置器:containerconfigurer:配置依赖反转容器,建立整个框架的类型依赖注册和类型查找类之间的关系。
在系统中有一个依赖类引擎上下文环境:enginecontext,可以根据配置文件生成引擎,此引擎是负责根据类型接口从容器中返回对象。
系统默认引擎nopengine,若没有配置有效的引擎,即用默认引擎,生成的引擎保存在单例容器中。
它们的关系如下:
系统在类mvcapplication的方法application_start中初始化引擎上下文。并通过调用enginecontext.initialize(false);实现所有反转依赖的注册功能;
5、容器注册类
系统注册接口为:idependencyregistrar,系统通过containerconfigurer注册此接口以及实现类的,并通过itypefinder类搜寻程序集里实现接口idependencyregistrar的类。代码如下:
namespace nop.core.infrastructure.dependencymanagement { /// <summary> /// configures the inversion of control container with services used by nop. /// </summary> public class containerconfigurer { public virtual void configure(iengine engine, containermanager containermanager, eventbroker broker, nopconfig configuration) { //other dependencies containermanager.addcomponentinstance<nopconfig>(configuration, "nop.configuration"); containermanager.addcomponentinstance<iengine>(engine, "nop.engine"); containermanager.addcomponentinstance<containerconfigurer>(this, "nop.containerconfigurer"); //type finder containermanager.addcomponent<itypefinder, webapptypefinder>("nop.typefinder"); //register dependencies provided by other assemblies var typefinder = containermanager.resolve<itypefinder>(); containermanager.updatecontainer(x => { var drtypes = typefinder.findclassesoftype<idependencyregistrar>(); var drinstances = new list<idependencyregistrar>(); foreach (var drtype in drtypes) drinstances.add((idependencyregistrar)activator.createinstance(drtype)); //sort drinstances = drinstances.asqueryable().orderby(t => t.order).tolist(); foreach (var dependencyregistrar in drinstances) dependencyregistrar.register(x, typefinder); }); //event broker containermanager.addcomponentinstance(broker); } } }
而接口idependencyregistrar的内容如下:
namespace nop.core.infrastructure.dependencymanagement { public interface idependencyregistrar { /// <summary> /// 此方法在通过containerbuilder注册依赖关系。 /// </summary> /// <param name="builder">容器管理者类</param> /// <param name="typefinder">类型查找者接口</param> void register(containerbuilder builder, itypefinder typefinder); /// <summary> /// 注册排序序号 /// </summary> int order { get; } } }
6、单例类容器
单例类系列保存系统中与程序相同生命周期的单例对象,或者叫做单例类容器。
其中包括实体类,集合类和字典类的单例容器。
singleton<t>,singletonlist<t>,singletondictionary<tkey, tvalue>。enginecontext就是通过singleton<t>类来管理引擎的。
7、mvc 服务提供类。
类型依赖获取器:nopdependencyresolver,通过继承mvc下的接口:idependencyresolver,并在application_start方法中注册,使之在系统启动时调用。
//set dependency resolver var dependencyresolver = new nopdependencyresolver(); dependencyresolver.setresolver(dependencyresolver);
8、其他
事件拦截类:eventbroker:过滤向系统发送的请求,防止由于临时的错误或异常导致系统崩溃。
系统启动时执行任务:istartuptask,启动时执行的任务主要是数据库的初始化和加载。