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

AOP:面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单独处理。比如事务、日志和安全等。

一.配置与注册Services和Repositories

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StructureMap; namespace TYStudioDemo.StructureMap
{
public class BootStrapper
{
public static void ConfigureStructureMap()
{
ObjectFactory.Configure(x =>
{
x.AddRegistry(new TYStudioDemoStructureMapRegistry());
x.Scan(scanner =>
{
scanner.Assembly("TYStudioDemo.Services");
scanner.Assembly("TYStudioDemo.Repositories");
});
});
}
}
}

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using StructureMap.Configuration.DSL;
using TYStudioDemo.Models;
using TYStudioDemo.DTO;
using TYStudioDemo.Interfaces;
using TYStudioDemo.Services;
using TYStudioDemo.Repositories; namespace TYStudioDemo.StructureMap
{
public class TYStudioDemoStructureMapRegistry : Registry
{
//注册接口实际使用的实现类
public TYStudioDemoStructureMapRegistry()
{
SelectConstructor<TYEntities>(() => new TYEntities()); //Exception Handle
For<ITYExceptionService>().Use<TYExceptionService>(); //Services
For(typeof(ISupplierService)).Use(typeof(SupplierService)); //Repositories
For(typeof(ISupplierRepository<>)).Use(typeof(SupplierRepository));
For(typeof(IProductRepository<>)).Use(typeof(ProductRepository));
}
}
}

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

二.创建Controller Factory

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using StructureMap; namespace TYStudioDemo.StructureMap
{
public class TYStudioDemoStructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, System.Type controllerType)
{
if (controllerType != null)
{
Controller c = ObjectFactory.GetInstance(controllerType) as Controller;
//当返回一个错误页面,View一级异常会被触发
c.ActionInvoker = new ErrorHandlingActionInvoker(new HandleErrorAttribute());
return c;
}
else
return null;
}
}
}

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc; namespace TYStudioDemo.StructureMap
{
public class ErrorHandlingActionInvoker : ControllerActionInvoker
{
private readonly IExceptionFilter filter; public ErrorHandlingActionInvoker(IExceptionFilter filter)
{
if (filter == null)
throw new ArgumentNullException("Exception filter is missing"); this.filter = filter;
} protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDes criptor actionDes criptor)
{
var filterInfo = base.GetFilters(controllerContext, actionDes criptor);
filterInfo.ExceptionFilters.Add(this.filter);
return filterInfo;
}
}
}

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

三.配置Global.asax文件

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

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using TYStudioDemo.StructureMap; namespace TYStudioDemo.WebUI
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth(); //注册StructureMap
BootStrapper.ConfigureStructureMap(); //通过StructureMap返回Controller实例,通过构造器注入
ControllerBuilder.Current.SetControllerFactory(new TYStudioDemoStructureMapControllerFactory());
} protected void Application_EndRequest(object sender, EventArgs e)
{
TYStudioDemo.Models.TYEntities.Cleanup();
}
}
}

ok,到此StructureMap的配置就全部完成了,接下来我们该怎么使用它呢。 文章开头已经告诉大家了我们使用Constructor构造器的方式进行依赖注入。 Controller的写法 既然是构造器就要写构造函数了,见下面写法:

 ISupplierService _supplierService;

         public SupplierController(ITYExceptionService tyExceptionService,
ISupplierService supplierService)
{
_tyExceptionService = tyExceptionService;
_supplierService = supplierService; }

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

 ISupplierRepository<Supplier> _supplierRepository;
IProductRepository<Product> _productRepository; public SupplierService(ISupplierRepository<Supplier> supplierRepotitory,
IProductRepository<Product> productRepository)
{
_supplierRepository = supplierRepotitory;
_productRepository = productRepository;
}

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

总结:

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

StructureMap依赖注入的更多相关文章

  1. MVC使用StructureMap实现依赖注入Dependency Injection

    使用StructureMap也可以实现在MVC中的依赖注入,为此,我们不仅要使用StructureMap注册各种接口及其实现,还需要自定义控制器工厂,借助StructureMap来生成controll ...

  2. DI 依赖注入之StructureMap框架

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

  3. ABP(现代ASP.NET样板开发框架)系列之6、ABP依赖注入

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  4. ABP框架 - 依赖注入

    文档目录 本节内容: 什么是依赖注入 传统方式的问题 解决方案 构造器注入模式 属性注入模式 依赖注入框架 ABP 依赖注入基础 注册依赖 约定注入 辅助接口 自定义/直接 注册 使用IocManag ...

  5. Unity依赖注入使用详解

    写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...

  6. ABP理论学习之依赖注入

    返回总目录 本篇目录 什么是依赖注入 传统方式产生的问题 解决办法 依赖注入框架 ABP中的依赖注入基础设施 注册 解析 其他 ASP.NET MVC和ASP.NET Web API集成 最后提示 什 ...

  7. # ASP.NET Core依赖注入解读&使用Autofac替代实现

    标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...

  8. 基于DDD的.NET开发框架 - ABP依赖注入

    返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  9. TypeC一个微软开发的超简单.NET依赖注入/IoC容器

    控制反转(IoC,Inversion of Control)是由Martin Fowler总结出来的一种设计模式,用来减少代码间的耦合.一般而言,控制反转分为依赖注入(Dependency Injec ...

随机推荐

  1. Java 命令行运行参数

    Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOME"bin"java –option 来启动,-option为虚拟 ...

  2. SUSE11&12 永久关闭防火墙

    SUSE11下:关闭操作为:service SuSEfirewall2_setup stopservice SuSEfirewall2_init stop取消开机启动防火墙:chkconfig SuS ...

  3. 36. Valid Sudoku (Array; HashTable)

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  4. 对象之int介绍

    #Auther Bob #--*--conding:utf-8 --*-- #创建两个int的对象,age1和age2 age1 = 10 age2 = int(1) #查看对象的类 print(ty ...

  5. 关于mybatis缓存配置详解

    一级缓存: 一级缓存是默认的. 测试:在WEB页面同一个查询执行两次从日志里面看同样的sql查询执行两次. 2次sql查询,看似我们使用了同一个sqlSession,但是实际上因为我们的dao继承了S ...

  6. Docker常见问题

    问题 当我使用docke search mysql时,显示如下错误: [root@iZ25u61v97hZ opt]# docker search redis Segmentation Fault o ...

  7. mysql只保留一条有效数据,删除其他重复的数据

    delete from TableName where id in( SELECT ID FROM(SELECT * FROM TableName t0WHERE(t0.Field1,t0.Field ...

  8. MongoDb进阶实践之四 MongoDB查询命令详述

    一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命名和删除.有了这些基 ...

  9. 求N的阶乘N!中末尾0的个数

    求N的阶乘N!中末尾0的个数 有道问题是这样的:给定一个正整数N,那么N的阶乘N!末尾中有多少个0呢?例如:N=10,N=3628800,则N!的末尾有两个0:直接上干货,算法思想如下:对于任意一个正 ...

  10. Debian 采用 iso 镜像作为 apt 源

    1.将N个debian-506-amd64-DVD-N.iso存放于本地或其他媒介内,本例是放在本机/iso/目录下2.创建N个挂载点目录 如下: debian:~#mkdir –r /media/d ...