终于到了题目中的MVC使用StructureMap依赖注入的配置与实现了。在ASP.Net三层架构应用中StructureMap的是最老的IOC/DI工具,也就是依赖注入,很多线上的项目都使用了StructureMap,非常酷的是他是免费的,具体的IOC/DI的设计思想本篇文章不做介绍,想研究可以百度一下,资料很多,哎说道百度想起google一堆泪啊,自从google撤出中国,google是经常的无法访问,很无奈啊很无奈。

依赖注入主要有两种方式:一种是Setter and Getter,一种是构造函数方式。天屹的这套框架使用的后者Constructor构造器的方式。如果你看了前面的文章,就会发现每个Service和Controller中都会有一个构造方法,没错我们就是使用的它们,接下详细的介绍一下StructureMap是怎么在我们的项目中实现依赖注入的。

一.配置与注册Services和Repositories

首先我们告诉StructureMap,我们需要注入的是什么,本系统中需要注册的是Services和Repositories,分别注入到Controller和Service。下面是具体写法,为什么这么写,不必较真,写法是StructureMap提供给我们的,使用就好了。

查看代码    
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using StructureMap;
  7.  
  8. namespace TYStudioDemo.StructureMap
  9. {
  10.     public class BootStrapper
  11.     {
  12.         public static void ConfigureStructureMap()
  13.         {
  14.             ObjectFactory.Configure(x =>
  15.             {
  16.                 x.AddRegistry(new TYStudioDemoStructureMapRegistry());
  17.  
  18.                 x.Scan(scanner =>
  19.                 {
  20.                     scanner.Assembly("TYStudioDemo.Services");
  21.                     scanner.Assembly("TYStudioDemo.Repositories");
  22.                 });
  23.             });
  24.         }
  25.     }
  26. }

上面的代码告诉了StructureMap去哪里找我们的Service和Repositories。同时TYStudioDemoStructureMapRegistry这个类告诉了StructureMap该用哪个类去实例化我们的接口,下面是TYStudioDemoStructureMapRegistry的代码:

查看代码    
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. using StructureMap.Configuration.DSL;
  7. using TYStudioDemo.Models;
  8. using TYStudioDemo.DTO;
  9. using TYStudioDemo.Interfaces;
  10. using TYStudioDemo.Services;
  11. using TYStudioDemo.Repositories;
  12.  
  13. namespace TYStudioDemo.StructureMap
  14. {
  15.     public class TYStudioDemoStructureMapRegistry : Registry
  16.     {
  17.         //注册接口实际使用的实现类
  18.         public TYStudioDemoStructureMapRegistry()
  19.         {
  20.             SelectConstructor<TYEntities>(() => new TYEntities());
  21.  
  22.             //Exception Handle
  23.             For<ITYExceptionService>().Use<TYExceptionService>();
  24.  
  25.             //Services
  26.             For(typeof(ISupplierService)).Use(typeof(SupplierService));
  27.  
  28.             //Repositories
  29.             For(typeof(ISupplierRepository<>)).Use(typeof(SupplierRepository));
  30.             For(typeof(IProductRepository<>)).Use(typeof(ProductRepository));
  31.         }
  32.     }
  33. }

现在我们已经配置了StructureMap并且注册了Service和Repository,接下来该告诉系统去使用StructureMap去实例化我们的Controller。

二.创建Controller Factory

既然使用了依赖注入,Controller的实例化当然不能再用系统本身的了,所以我们需要创建一个ControllerFactory:TYStudioDemoStructureMapControllerFactory。

查看代码    
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Web.Mvc;
  7. using StructureMap;
  8.  
  9. namespace TYStudioDemo.StructureMap
  10. {
  11.     public class TYStudioDemoStructureMapControllerFactory : DefaultControllerFactory
  12.     {
  13.         protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
  14.         {
  15.             if (controllerType != null)
  16.             {
  17.                 Controller c = ObjectFactory.GetInstance(controllerType) as Controller;
  18.  
  19.                 //当返回一个错误页面,View一级异常会被触发
  20.                 c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorAttribute());
  21.                 return c;
  22.             }
  23.             else
  24.                 return null;
  25.         }
  26.     }
  27. }

TYStudioDemoStructureMapControllerFactory继承自DefaultControllerFactory,DefaultControllerFactory是MVC默认的Controller Factory,然后重新器获得Controller实例的方法,由StructureMap的ObjectFactory来创建实例,StructureMap会帮我们把Controller构造函数中的参数实例化。

上面的ErrorHandlingActionInvoker方法:

查看代码    
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web.Mvc;
  6.  
  7. namespace TYStudioDemo.StructureMap
  8. {
  9.     public class ErrorHandlingActionInvoker : ControllerActionInvoker
  10.     {
  11.         private readonly IExceptionFilter filter;
  12.  
  13.         public ErrorHandlingActionInvoker(IExceptionFilter filter)
  14.         {
  15.             if (filter == null)
  16.                 throw new ArgumentNullException("Exception filter is missing");
  17.  
  18.             this.filter = filter;
  19.         }
  20.  
  21.         protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
  22.         {
  23.             var filterInfo = base.GetFilters(controllerContext, actionDescriptor);
  24.             filterInfo.ExceptionFilters.Add(this.filter);
  25.             return filterInfo;
  26.         }
  27.     }
  28. }

Controller Factory创建ok。但是这样系统是不会使用我们自己的Controller Factory的,所以需要通知一下MVC系统。

三.配置Global.asax文件

在Application_Start()方法中也就是项目启动的时候注册StructureMap并通知系统使用我们自己的Controller Factory进行实例化Controller。

查看代码    
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Http;
  6. using System.Web.Mvc;
  7. using System.Web.Optimization;
  8. using System.Web.Routing;
  9. using TYStudioDemo.StructureMap;
  10.  
  11. namespace TYStudioDemo.WebUI
  12. {
  13.     // Note: For instructions on enabling IIS6 or IIS7 classic mode,
  14.     // visit http://go.microsoft.com/?LinkId=9394801
  15.  
  16.     public class MvcApplication : System.Web.HttpApplication
  17.     {
  18.         protected void Application_Start()
  19.         {
  20.             AreaRegistration.RegisterAllAreas();
  21.  
  22.             WebApiConfig.Register(GlobalConfiguration.Configuration);
  23.             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  24.             RouteConfig.RegisterRoutes(RouteTable.Routes);
  25.             BundleConfig.RegisterBundles(BundleTable.Bundles);
  26.             AuthConfig.RegisterAuth();
  27.  
  28.             //注册StructureMap
  29.             BootStrapper.ConfigureStructureMap();
  30.  
  31.             //通过StructureMap返回Controller实例,通过构造器注入
  32.             ControllerBuilder.Current.SetControllerFactory(new TYStudioDemoStructureMapControllerFactory());
  33.         }
  34.  
  35.         protected void Application_EndRequest(object sender, EventArgs e)
  36.         {
  37.             TYStudioDemo.Models.TYEntities.Cleanup();
  38.         }
  39.     }
  40. }

ok,到此StructureMap的配置就全部完成了,接下来我们该怎么使用它呢。

文章开头已经告诉大家了我们使用Constructor构造器的方式进行依赖注入。

四.Controller的写法

既然是构造器就要写构造函数了,见下面写法:

查看代码    
  1. ISupplierService _supplierService;
  2.  
  3. public SupplierController(ITYExceptionService tyExceptionService,
  4.                             ISupplierService supplierService)
  5. {
  6.     _tyExceptionService = tyExceptionService;
  7.     _supplierService = supplierService;
  8.  
  9. }

在构造方法中加入我们要注入的Service接口,然后StructureMap就会根据上面TYStudioDemoStructureMapRegistry的配置去创建我们需要实例化的service对象了。

同样向Service中注入Repository的写法是一样的:

查看代码    
  1. ISupplierRepository<Supplier> _supplierRepository;
  2. IProductRepository<Product> _productRepository;
  3.  
  4. public SupplierService(ISupplierRepository<Supplier> supplierRepotitory,
  5.                             IProductRepository<Product> productRepository)
  6. {
  7.     _supplierRepository = supplierRepotitory;
  8.     _productRepository = productRepository;
  9. }

至此StructureMap配置与使用就全部完成了。

总结:

我们发现,我们的参数都是接口类型了,这样的好处就是将来对ISupplierService的实现不一样了,我们只需要重写写一个ISupplierService的实现了,并修改TYStudioDemoStructureMapRegistry使ISupplierService使用新的实现类,就可以了。因为我们使用的都是接口所以方法和参数都是固定的,所以呢~~ Controller中不用修改任何代码,同理Service也是一样的。这样就充分的降低了代码之间的耦合度。

下篇文章将介绍使用Enterprise Library 5.0 实现异常与日志的处理。

转自:http://www.tystudio.net/2013/04/06/mvc-structuremap-config/

StructureMap使用方法(转)的更多相关文章

  1. CSS、HTML5、JS

    [att*=value]{}包含value属性的所有元素样式.[id*=div]{} a[href$=jpg]:after{} [att^=value]{}开头字符包含value属性的所有元素样式 [ ...

  2. 用ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统

    用http://ASP.NET MVC5 +SQLSERVER2014搭建多层架构的数据库管理系统 背景:前段时间,给一家公司做外包(就是图标是朵菊花那家).为了尽快实现交付,网上四处寻找适合中小型企 ...

  3. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  4. .Net中的AOP系列之《间接调用——拦截方法》

    返回<.Net中的AOP>系列学习总目录 本篇目录 方法拦截 PostSharp方法拦截 Castle DynamicProxy方法拦截 现实案例--数据事务 现实案例--线程 .Net线 ...

  5. StructureMap 代码分析之Widget 之Registry 分析 (1)

    说句实话,本人基本上没用过Structuremap,但是这次居然开始看源码了,不得不为自己点个赞.Structuremap有很多的类,其中有一个叫做Widget的概念.那么什么是Widget呢?要明白 ...

  6. StructureMap 学习笔记(1)

    前言 一个偶然的机会接触到了StructureMap,当时客户要求让程序具有较好的测试性,自然而然就想到了IOC 容器. 之后就去Google了一下, 不经意间在StackOverFlow找到一篇帖子 ...

  7. StructureMap依赖注入

    IOC:控制反转,是一种设计模式.一层含义是控制权的转移:由传统的在程序中控制依赖转移到由容器来控制:第二层是依赖注入:将相互依赖的对象分离,在spring配置文件中描述他们的依赖关系.他们的依赖关系 ...

  8. DI 依赖注入之StructureMap框架

    DI  依赖注入之StructureMap框架 一.简叙: structureMap只是DI框架中的其中之一. 二.安装及使用: 1.懒人方法: 使用MVC5项目时,可以直接在nuget程序包中安装S ...

  9. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

随机推荐

  1. PHP的学习--cookie和session--来自copy_02

    PHP的学习--cookie和session   最近读了一点<PHP核心技术与最佳实践>,看了cookie和session,有所收获,结合之前的认识参考了几篇博客,总结一下-- 1. P ...

  2. 【Go语言】集合与文件操作

    本文目录 1.数据集合的主要操作 1_1.字典的声明 1_2.字典的初始化和创建 1_3.字典的访问和操作 1_4.其他类型的数据集 2.文件操作 2_1.文件操作概述os包和path包 2_2.文件 ...

  3. 处理海量数据的高级排序之——归并排序(C++)

    代码实现                                                                                                 ...

  4. 【hihoCoder】1041. 国庆出游

    问题:详见http://hihocoder.com/problemset/problem/1041 有n个城市,城市编号为1-n,城市间有n-1条路(所以,城市路网是一棵树).给定一个序列S,要求判断 ...

  5. bzoj3594: [Scoi2014]方伯伯的玉米田--树状数组优化DP

    题目大意:对于一个序列,可以k次选任意一个区间权值+1,求最长不下降子序列最长能为多少 其实我根本没想到可以用DP做 f[i][j]表示前i棵,操作j次,最长子序列长度 p[x][y]表示操作x次后, ...

  6. asl 和 lgpl的区别

    按照使用条件的不同,开源软件许可证可以分为三类(严苛程度递减) 1. 使用该开源软件的代码再散布(redistribute)时,源码也必须以相同许可证公开. 代表许可类型:GPL, AGPL 2. 使 ...

  7. MUI - 侧滑菜单

    各大APP必备的侧滑菜单栏,支持手势滑动.包含QQ式.美团式等 结构模板 这里是示例Html, 必须使用Mui框架才能使用. 主容器 <div class="mui-off-canva ...

  8. 打开网页自动弹出QQ对话框的实现办法

    Ian今天偶然进入一个公司的企业网站,然后QQ聊天窗口这里马上就弹出与那个公司客服聊天的窗口.怀着好奇的心态,Ian分析了该公司的网站源码,发现了实现网页弹出qq对话框的原理与实现方法,相信此时此刻你 ...

  9. 使用花生壳6.5客户端FTP设置

    1.打开FTP客户端—选项—参数选择 2.设置为主动模式(PORT) 3.连接FTP服务器 4.FTP连接成功

  10. HDU 4287 Intelligent IME(字典树数组版)

    Intelligent IME Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...