StructureMap 的使用
IoC 我听过很多遍,上班的时候也用着。总觉得时间不够,隔周周六还要上班,烦躁的时候,根本就没心情去理会这些东西。最近突然就闲下来了,也许也不是闲下来了,只是有些需求有点莫名其妙,我觉得我应该拒绝些东西,便委婉回绝了。
牢骚发过了,我改整理下知识了:
IoC 即 Inversion Of Control 翻译过来 就是 控制器翻转,或者 叫做 依赖注入 即 Dependence Inject(ion) 。
到底有什么好处? 低耦合,使各个部件关联性小,容易维护。在编译时并不会检查其关联合法性,而是在运行时才检查。
有很多这样的组件,如NInject 。而 我们项目中使用的是 StructureMap 也及时标题所述。
先前,我尝试自己编写,集成DefaultControllerFactory,重写其虚函数
GetControllerInstance,并设置成默认的
ControllerFactory(ControllerBuilder.Current.SetControllFactory(factory))
似乎都已失败告终,知识层面估计是还不到家吧。那么先学会使用别人的东西。
StructureMap 据说是比较早的东西了,经典才会被延续。
主要的过程是这样的:
1、新建类(MyControllerFactory)继承DefaultControllerFactory 重写 GetControllerInstance()
2、在程序运行时(Application_Start())注册到系统中(就是指定一个ControllerFacotry 实例,也就是自己写的那个)
3、重写 configure() 并添加注册到 StructureMap 对应类库中。而我粗览了下NInject没有配置这一关。
对于1、2所属的关键词 都是 System.Web.Mvc 里面的内容,我们先来看一下 GetControllerInstance()
类库中是这样写的,
如果controllerType为null则,返回一个异常(暂且也不用管是啥异常)。
然后判断是否能够获取到指定类型的实例,如果不能,抛出一个异常。
在不满足前两个条件的前提下,使用ControllerActivator创建一个实例。
当然,我们不能使用默认的方式创建实例,因此关键就是换掉这一句。
查找StructureMap类库:
因此我使用 ObjectFactory.GetInstance(requestContext,controllerType); 来替换上面系统默认的创建实例的方法。
但是实际使用的时候发现 判断条件中的 异常处理的 MvcResources 无法找到。那么我是这样处理的:
if (controllerType == null || !typeof(IController).IsAssignableFrom(controllerType))
{
return base.GetControllerInstance(requestContext, controllerType);
}
把异常处理交给系统的GetControllerInstance去处理,而生成实例由 StructureMap 来担任。
至此,我们仅仅只是实现了类。现在我们要注册到系统中:(在Application_Start() 中)
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());
接下来,就是重写配置 configure(); 在类库中搜索 改 虚函数:
因此,我们创建一个类,继承Registry,并将其注册到StractureMap 配置中(AddRegistry)。
可是我们点进去却发现:
configure 没有东西。不知道了,网上找吧:
public class StoreRegistry : Registry
{
protected override void configure()
{
// 每添加新接口,则往这里添加一条语句,对应其继承类。
ForRequestedType<ITestService>() // 接口
.TheDefaultIsConcreteType<TestService>(); //继承类
}
}
最后将此Registryt添加到StructureMapConfiguration中:
public class Bootstrapper
{
public static void SetStroreRegistry()
{
StructureMapConfiguration.AddRegistry(new StoreRegistry());
}
}
这样整个StuctureMap 就成功签入了系统中了。
我们这样使用: