庖丁解牛Nop:控制反转--IOC和DI
IOC中文名被称作控制反转(Inversion of Control),DI被称为依赖注入(Dependency Injection);
使用控制反转开发模式是先开发接口,然后再实现类。这种方法却可以有效的降低类之间的互相依赖的情况,不但能增加架构的弹性,也能有效的降低软件的复杂度。
NopCommerce将所有和Autofac注入相关的工作都放到了EngineContext中,在Global.asax的Application_Start函数的第一句代码:
//initialize engine context
EngineContext.Initialize(false);
从这里开始EngineContext的初始化工作,初始化时会创建一个新的NopEngine,参数false指定当NopEngine不为空时是否重新生成一个新的NopEngine。
Initialize()函数在EngineContext.cs中:如下图:
[MethodImpl(MethodImplOptions.Synchronized)]
public static IEngine Initialize(bool forceRecreate)//传入的参数是false or true
{
if (Singleton<IEngine>.Instance == null || forceRecreate)
{
var config = ConfigurationManager.GetSection("NopConfig") as NopConfig;
Debug.WriteLine("Constructing engine " + DateTime.Now);
Singleton<IEngine>.Instance = CreateEngineInstance(config);
Debug.WriteLine("Initializing engine " + DateTime.Now);
Singleton<IEngine>.Instance.Initialize(config);
}
return Singleton<IEngine>.Instance;
}
NopEngine使用单例模式,在整个程序运行期间存在一个实例,代码首先会判断NopEngine是否为空,为空的话则根据web.config中配 置的NopConfig节点信息
创建一个新的NopEngine实例,然后对该实例进行初始化操作。
web.config中的配置信息如下:
<configSections>
<section name="NopConfig" type="Easy.Core.Configuration.NopConfig, Easy.Core" requirePermission="false" />
</configSections>
<NopConfig>
<DynamicDiscovery Enabled="true" />
<Engine Type="" />
<Themes basePath="~/Themes/" />
</NopConfig>
CreateEngineInstance()函数的作用使用new NopEngine()创建了一个NopEngine实例,在NopEngine的构造函数处对Autofac的容器(Container)作了初始化
代码:public NopEngine(EventBroker broker, ContainerConfigurer configurer)
{
var config = ConfigurationManager.GetSection("NopConfig") as NopConfig;
InitializeContainer(configurer, broker, config);
}
private void InitializeContainer(ContainerConfigurer configurer, EventBroker broker, NopConfig config)
{
var builder = new ContainerBuilder();
_containerManager = new ContainerManager(builder.Build());
configurer.Configure(this, _containerManager, broker, config);
}
NopCommerce通过ContainerManager对容器做了一层封装,方便对其他类型的IOC框架的扩充和支持。Configure函数完成了所有依赖的注入,同时查找所有实现了IDependencyRegistrar接 口的类,
并调用其Register方法,注册内容包括Http context、web helper、controller、data layer、plugin、cache manager、work context、services、settings、event consumers等等。
ContainerManager/ContainerConfigurer和IDependencyRegistrar是实现IOC的关键
ContainerManagerContainerManager对依赖注入中使用的容器做了一层封装,提供了这些函数:
- AddComponent/AddComponentInstance/AddComponentWithParameters
- Resolve/ResolveAll/ResovleUnregistered
- UpdateContainer
DependencyRegistrar:
- web helper
- controller
- data layer
- plugin
- cache manager
- work context
- services
- settings
- event consumer