本文转自:http://www.cnblogs.com/Hai--D/p/5992573.html

var builder = new ContainerBuilder();

// Mvc Register
builder.RegisterControllers(Assembly.GetExecutingAssembly()).AsSelf().PropertiesAutowired();
builder.RegisterFilterProvider();
builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope(); //WebApi Register
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).AsSelf().PropertiesAutowired();
builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
builder.RegisterWebApiModelBinderProvider(); var container = builder.Build(); // Set the dependency resolver for Web API.
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver; // Set the dependency resolver for MVC.
var resolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(resolver);

  

在实际Controller和ApiController中通过构造函数注入,这不必多说。

但是,在实际项目需求的时候,有些地方不方便使用构造函数,或者说就要使用服务定位IContainer.Resolve(ServiceType)的方式来获得服务的实例。

曾经在项目中看到过有人通过把Container设区全局静态变量来获得对象容器。这个方式在Local的情况下,不会有太大问题。在Mvc中,容器DependencyResolver.Current本身也是通过尽量变量来实现的。

 public class DependencyResolver
{
public DependencyResolver(); public static IDependencyResolver Current { get; }
...
}

  

但是和C端不同的是,Web服务是基于请求的,autofac内部的InstancePerLifetimeScope,InstancePerHttpRequest,InstancePerApiRequest等都是基于每次请求的Scope,而静态的Container明显生命周期不符合。

所以我们写代码的时候都是通过DependencyResolver.Current.GetService()和GlobalConfiguration.Configuration.DependencyResolver.GetService()来分别获取Mvc和WebApi的对象。那么问题来了,我有一段业务逻辑在BLL中,Mvc和WebApi可以都调用到,其中需要Resolve一个服务,那么如何来指定容器呢?

带着问题,我们先来看看DependencyResolver.Current和GlobalConfiguration.Configuration.DependencyResolver,通过一组实验来对比一下:

 public class WebApiApplication : System.Web.HttpApplication
{
public static System.Web.Mvc.IDependencyResolver mvcResolver;
public static System.Web.Http.Dependencies.IDependencyResolver apiResolver; protected void Application_Start()
{
...
       builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope(); // Set the dependency resolver for Web API.
var webApiResolver = new AutofacWebApiDependencyResolver(container);
apiResolver = webApiResolver;
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver; // Set the dependency resolver for MVC.
var resolver = new AutofacDependencyResolver(container);
mvcResolver = resolver;
DependencyResolver.SetResolver(mvcResolver);
}
}    public interface IUserService
{
} public class UserService : IUserService
{
}

  我们分别定义了两个静态变量mvcResolver和apiResolver来存储两个不同的容器,并注册了一组服务,指定其生命周期为InstancePerLifetimeScope,先看看Mvc的容器

 public class HomeController : Controller
{
IUserService _userservice; public HomeController(IUserService userService)
{
_userservice = userService;
var a = DependencyResolver.Current.GetService<IUserService>();
var b = WebApiApplication.mvcResolver.GetService<IUserService>();
var c1 = ReferenceEquals(userService, a); //true
var c2 = ReferenceEquals(userService, b); //true
var c3 = ReferenceEquals(b, a); //true
}
} public class ValuesController : ApiController
{
IUserService _userservice; public ValuesController(IUserService userService)
{
_userservice = userService;
var a = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserService));
var b = WebApiApplication.apiResolver.GetService(typeof(IUserService));
var c1 = ReferenceEquals(userService, a); //false
var c2 = ReferenceEquals(userService, b); //false
var c3 = ReferenceEquals(b, a); //true
}
}

  

发现通过GlobalConfiguration.Configuration.DependencyResolver来获取的对象,竟然不等于构造函数解析出来的对象,有点毁三观。说明它并不是当前上下文的对象,也就是说这个对象的生命周期不在控制范围内。

那么Mvc和WebApi可不可以用同一个容器来指定呢?

我们先来看看stackoverflow上的这篇文章:Is it possible to configure Autofac to work with ASP.NET MVC and ASP.NET Web Api

其实Mvc和WebApi分别是两个独立的依赖解析器,这点没什么问题,一个是System.Web.Mvc.IDependencyResolver另一个是System.Web.Http.Dependencies.IDependencyResolver,两个互相不串。

最后,一个很重要的对象来了,那就是Autofac.IComponentContext,它就是解析的上下文,通过它来解析的对象是符合当前上下文的,我们再来看看之前的例子:

public class HomeController : Controller
{
IUserService _userservice; public HomeController(IUserService userService, IComponentContext com)
{
_userservice = userService;
var a = DependencyResolver.Current.GetService<IUserService>();
var b = WebApiApplication.mvcResolver.GetService<IUserService>();
var d = com.Resolve<IUserService>();
var d1 = ReferenceEquals(userService, d); //true
var c1 = ReferenceEquals(userService, a); //true
var c2 = ReferenceEquals(userService, b); //true
var c3 = ReferenceEquals(b, a); //true
}
}

  

//WebApi:
public class ValuesController : ApiController
{
IUserService _userservice; public ValuesController(IUserService userService, IComponentContext com)
{
_userservice = userService;
var a = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IUserService));
var b = WebApiApplication.apiResolver.GetService(typeof(IUserService));
var d = com.Resolve<IUserService>();
var d1 = ReferenceEquals(userService, d); //true
var c1 = ReferenceEquals(userService, a); //false
var c2 = ReferenceEquals(userService, b); //false
var c3 = ReferenceEquals(b, a); //true
}
}

  

参考:

ASP .Net 4 Web Api RC + Autofac manual resolving

希望对你有帮助,如有错误,欢迎指出! 用属性自动注入需要是public,

如果,能支持 protected 注入,那就完美了

转:autofac在mvc和webapi集成的做法的更多相关文章

  1. autofac解析Mvc和Webapi的坑

    我们在项目中很早就开始使用autofac,也以为知道与mvc和webapi集成的做法. var builder = new ContainerBuilder(); // Mvc Register bu ...

  2. autofac + owin + webform + mvc + webapi集成demo

    http://git.oschina.net/shiningrise/AutofacOwinDemo using Microsoft.Owin; using Owin; using System.We ...

  3. Autofac 同时支持MVC 与Webapi

    1.引用 using Autofac; using Autofac.Integration.Mvc; using Autofac.Integration.WebApi; 2.在Global中的Appl ...

  4. AutoFac mvc和WebAPI 注册Service (接口和实现)

    AutoFac  mvc和WebAPI  注册Service (接口和实现) 1.准备组件版本:Autofac 3.5.0    Autofac.Integration.Mvc 3.3.0.0  (I ...

  5. 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入

    系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...

  6. AutoFac在MVC中的使用

    在asp.net mvc控制器中使用Autofac来解析依赖 如下Controller中使用构造函数依赖注入接口IUserService: public IUserService _IUserServ ...

  7. 记一次autofac+dapper+mvc的框架搭建实践

    1,环境 .net framework4.7.2,Autofac,Autofac.Mvc5,sql server 2,动机 公司项目用的是ef,之前留下代码的大哥,到处using,代码没有分层,连复用 ...

  8. 给Asp.Net MVC及WebApi添加路由优先级

    一.为什么需要路由优先级 大家都知道我们在Asp.Net MVC项目或WebApi项目中注册路由是没有优先级的,当项目比较大.或有多个区域.或多个Web项目.或采用插件式框架开发时,我们的路由注册很可 ...

  9. Autofac.Integration.Mvc分析

    Autofac.Integration.Mvc static ILifetimeScope LifetimeScope { get { return (ILifetimeScope)HttpConte ...

随机推荐

  1. IlRuntime + protobuf-net

    环境unity566,.net2.0 下载protobuf-net https://github.com/mgravell/protobuf-net/tree/r668 因为这个vs2015就可以打开 ...

  2. MySQL中锁问题

    1.脏读 脏页只是在缓冲池中已经修改的页但是没有刷新到磁盘中,即数据库实例内存中的页和磁盘中的页事不一致的,当然在刷新到磁盘之前,日志都已经被写入到了重做日志文件中,而所谓的脏数据是指事务对缓冲池中行 ...

  3. 我的Android进阶之旅------>Android使用百度地图时,关于android.permission.BAIDU_LOCATION_SERVICE的声明警告。

    [重要提醒] 定位SDKv3.1版本之后,以下权限已不需要,请取消声明,否则将由于Android 5.0多帐户系统加强权限管理而导致应用安装失败. <uses-permission androi ...

  4. scrapy+mongodb报错 TypeError: name must be an instance of str

    经过各种排查,最后找到原因,在settings文件中配置文件大小写写错了,在pipelines中 mongo_db=crawler.settings.get('MONGODB_DB'),get 获取的 ...

  5. Oracle11g用户频繁锁定并且解锁后不允许登录

    原因有可能是oracle的密码过期机制导致的:一.由于Oracle中默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”所导致.解决办法:1.查看用户用的哪种prof ...

  6. 阿里云公网IP不能使用

    1.开通专用网络 2.在ECS的安全组 创建 专用网络 3.配置规则 4.快速创建规则,增加自己需要入网的端口号,授权对象写:0.0.0.0/0

  7. Android开发问题:ActivityNotFoundException: Unable to find explicit activity class

    http://blog.csdn.net/debuglog/article/details/7236013 原因:AndroidManifest.xml未添加对应Activity配置. 解决办法:在A ...

  8. windows安装mysql教程2017最新

    1.首先在mysql官网下载最新版mysql, 附上链接点击打开链接,根据你的系统型号选择对应的包下载,大约300多兆,版本号为5.7.19 下载完之后,解压缩,是一个标准的mysql文件 2.第二步 ...

  9. Git配置出现的问题

    git是代码版本同步工具,适用于团队开发,进公司第一堂课就是配置Git.接下来就把其中遇到的问题记录一下,与大家共享一下. 首先,在Bitbucket上注册账户,之后给管理员说一下,让他邀请你加入开发 ...

  10. Windows读写文件的猫腻

    这里主要涉及对于回车换行的讨论. 回车:\r 换行:\n Windows读写文件分为普通文件读写和二进制文件读写. 如果以二进制的方式读写文件(如rb, wb),将会完全的把文件内容读出来,不做任何处 ...