1、常规写法,难道我们每次都new一个服务,如下面的UserService和CompanyService然后调用服务的Find方法去操作,为什么我们不让UserService和CompanyService服务注入进来呢? 

public ActionResult Index()
{
  DbContext context = new DbContext();
  IUserService userService = new UserService(context);
  User user = userService.Find<User>();

return View(user);
}
public ActionResult Index2()
{
  DbContext context = new DbContext();
  ICompanyService companyService = new CompanyService(context);   
Company company = companyService.Find<Company>(2);
   return View(company); 
}

2、我们想要的实际效果是MVC请求进来的时候,实例化控制器的时候,就把UserService和CompanyService服务注入进来,但是下面的带参数的控制器构造函数TestController(IUserService userService, ICompanyService companyService)MVC是实例化不了的,MVC只能实例化不带参数的构造函数TestController()

 public class TestController : Controller
{
private IUserService _iUserService = null;
private ICompanyService _iCompanyService = null;
/// <summary>
/// 构造函数注入---控制器得是由容器来实例化
/// </summary>
/// <param name="userService"></param>
/// <param name="companyService"></param>
public TestController(IUserService userService, ICompanyService companyService)
{
this._iUserService = userService;
this._iCompanyService = companyService;
}
}
public ActionResult Index()
{
  DbContext context = new DbContext();
  IUserService userService = this._iUserService;
  User user = userService.Find<User>();
return View(user);
}
public ActionResult Index2()
{
  DbContext context = new DbContext();
  ICompanyService companyService = this._iCompanyService;
Company company = companyService.Find<Company>();
   return View(company); 
}

 3、在“1、看源码MVC如何实例化控制器”中提到MVC实例化控制器使用的是ControllerBuilder.GetControllerFactory()得到一个DefaultControllerFactory工厂,然后用工厂的CreateController方法利用反射去创建Controller实例,那么我们可以把工厂换成自己实现的自定义工厂不就可以了吗,ControllerBuilder还有个SetControllerFactory方法,自定义的控制器工厂CustomControllerFactory继承DefaultControllerFactory,微软的特点是virtual和abstract都是让我们来扩展的,那么我们复写GetControllerInstance方法,在GetControllerInstance方法里去构建容器

public class CustomControllerFactory : DefaultControllerFactory
{
  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
IUnityContainer container = DIFactory.GetContainer();
//return base.GetControllerInstance(requestContext, controllerType);
return (IController)container.Resolve(controllerType);
}
}

4、在Application_Start中指定自定义的控制器工厂

public class MvcApplication : System.Web.HttpApplication
{protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();//注册区域
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);//注册全局的Filter
RouteConfig.RegisterRoutes(RouteTable.Routes);//注册路由
BundleConfig.RegisterBundles(BundleTable.Bundles);//合并压缩 ,打包工具 Combres
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());//设置自定义的控制器工厂
}
}

5、依赖注入

public class DIFactory
{
public static IUnityContainer GetContainer()
{
IUnityContainer container = null;
//container.RegisterType
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
container = new UnityContainer();
section.Configure(container, "MyContainer"); return container;
}
}

6、进行Unity配置

<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity>
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
<containers>
<container name="MyContainer">
<extension type="Interception"/>
<register type="System.Data.Entity.DbContext, EntityFramework" mapTo="SchoolManager.EF.Model.SchoolDBEntities, SchoolManager.EF.Model"/>
<register type="SchoolManager.Bussiness.Interface.ICompanyService,SchoolManager.Bussiness.Interface" mapTo="SchoolManager.Bussiness.Service.CompanyService, SchoolManager.Bussiness.Service"/>
<register type="SchoolManager.Bussiness.Interface.IUserService,SchoolManager.Bussiness.Interface" mapTo="SchoolManager.Bussiness.Service.UserService, SchoolManager.Bussiness.Service"/>
</container>
</containers>
</unity>
</configuration>

2、MVC+IOC容器+ORM结合的更多相关文章

  1. IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用

    Autofac结合EF在MVC中的使用,上一篇IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)已经介绍了.但是只是MVC中Co ...

  2. IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)

    转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html  有修改 Autofac通过Controller默认构造 ...

  3. IOC 容器在 ASP.NET MVC 中的应用

    IOC 容器在 ASP.NET MVC 中的应用 IOC:Inversion Of Control 翻译为控制反转,我们在面向对象软件开发过程中,一个应用程序它的底层结构可能由N种不同的构件来相互协作 ...

  4. IOC容器特性注入第六篇:利用MVC注入点,把容器启动

    这里是利用MVC三个注入点中的:IDependencyResolver 进行注入 在全局类中Global.asax代码如下: #region MVC Inject System.Web.Mvc.Dep ...

  5. SpringMVC系列(十五)Spring MVC与Spring整合时实例被创建两次的解决方案以及Spring 的 IOC 容器和 SpringMVC 的 IOC 容器的关系

    一.Spring MVC与Spring整合时实例被创建两次的解决方案 1.问题产生的原因 Spring MVC的配置文件和Spring的配置文件里面都使用了扫描注解<context:compon ...

  6. ASP.NET MVC不可或缺的部分——DI(IOC)容器及控制器重构的剖析

    ASP.NET MVC不可或缺的部分——DI(IOC)容器及控制器重构的剖析   IoC框架最本质的东西:反射或者EMIT来实例化对象.然后我们可以加上缓存,或者一些策略来控制对象的生命周期,比如是否 ...

  7. ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

    在正式进入主题之前我们来看下几个概念: 一.依赖倒置 依赖倒置是编程五大原则之一,即: 1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象. 2.抽象不能依赖于具体,具体依赖于抽象. 其中上层就 ...

  8. Spring MVC工作原理及源码解析(一) MVC原理介绍、与IOC容器整合原理

    MVC原理介绍 Spring MVC原理图 上图是Spring MVC工作原理图(图片来自网上搜索),根据上图,我们可以得知Spring MVC的工作流程如下: 1.用户(客户端,即浏览器)发送请求至 ...

  9. Spring框架IOC容器和AOP解析

    主要分析点: 一.Spring开源框架的简介  二.Spring下IOC容器和DI(依赖注入Dependency injection) 三.Spring下面向切面编程(AOP)和事务管理配置  一.S ...

随机推荐

  1. 【Luogu P1967】货车运输

    Luogu P1967 题目大意:给定一张图和q个询问,询问x节点和y节点的路径之间最小边权最大可以是多少. 可以发现对于一条边\(E(x,y)\),如果x到y有另一条路径且最小边权大于\(E(x,y ...

  2. 设计模式——代理模式(Proxy)

    定义 为其他对象提供一种代理,以控制对这个对象的访问.代理对象在客户端和目标对象之间起到中介的作用.(结构型) 如果不知道代理模式,可能大家对代理服务器都不叫熟悉.代替服务器代替请求者去发一起对另一个 ...

  3. csrf与xss

    CSRF攻击攻击原理及过程如下: 1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A:       2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登 ...

  4. 程序员的算法课(11)-KMP算法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  5. Prometheus 【目录】

    正在陆续更新,内容大体包括: rule.标签重置.cAdversior.自动发现(File 自动发现.DNS自动发现.k8s环境自动发现)等... 目录: prometheus[第一篇] Promet ...

  6. centos 7 MysSQL 5.7.23 二进制安装

    MySQL 5.7.23 二进制安装 CentOS 7 将默认数据库MySQL替换成了Mariadb. 这里会从系统的环境准备开始一步一步安装. 环境准备 系统版本 内核版本 IP地址 Centos ...

  7. surfer白化

    surfer白化的方法: 方法一: 1.griddata需白化的文件(surfer处理成grd格式,也就是surfer绘图的基本数据格式) 注意:用surfer转换格式时,插值间距(spacing)大 ...

  8. vsftpd cmds_allowed 权限控制

    vsftpd cmds_allowed cmds_allowed=ABOR,CWD,LIST,MDTM,MKD,NLST, PASS,PASV,PORT,PWD,QUIT,RETR,RMD,RNFR, ...

  9. shell脚本介绍、shell脚本结构和执行、date命令用法、shell脚本中的变量

    7月11日任务 20.1 shell脚本介绍20.2 shell脚本结构和执行20.3 date命令用法20.4 shell脚本中的变量 20.1 shell脚本介绍 1.shell脚本语言是linu ...

  10. 用墨卡托和GPS坐标计算距离时误差测试

    iOS墨卡托和GPS坐标计算距离时误差测试,测试结果: 墨卡托和gps坐标来回转换没有误差. 墨卡托坐标计算出的距离比gps坐标计算出的距离大,100/92*100 = 108米,每100米多算出8米 ...