本文转自: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. Server Objects Extension(SOE)开发(二)

    前言 SOE的提供了REST和Soap两种模板,只要在模板特定的方法中添加自己的业务逻辑代码即可,开发流程非常的简单便捷.那怎么知道自己的业务逻辑代码该写在模板的那个方法里面呢?这就需要很好的理解SO ...

  2. Java源码之String

    本文出自:http://blog.csdn.net/dt235201314/article/details/78330377 一丶概述 还记得那会的“Hello World”,第一个程序,输出的Str ...

  3. Python 学习之旅

    流程图 第一章  Python简介 第二章  Python基础 第三章  流程控制 第四章  字符编码 第五章  文件处理 第六章  函数 第七章 模块与包 第八章 面向对象 第九章 异常处理 第十章 ...

  4. Python获取主机名

    import socket print socket.gethostname()

  5. 关于like %%的优化思路

    测试数据:2亿行,被筛选出的数据,3KW多行. 众所周知 like %str%无法走索引,但是我们如果实在是有这种需求要达到like '%str%'的筛选目的,怎么优化好一些呢? 以下是我的一些思考: ...

  6. boost之实用工具

    1.noncopyable用于禁止复制和拷贝的类继承.声明拷贝和赋值函数为私有,将运行时的错误转化为编译期的错误. #include <iostream> #include <boo ...

  7. split命令

    语法:split [OPTION]... [INPUT [PREFIX]]常用参数说明: -a, --suffix-length=N            generate suffixes of l ...

  8. CuteEditor.Editor+a+a+c+a+a.a() System.RuntimeType.get_Assembly() 问题解决方法

    问题: Server Error in '/' Application. Attempt by method 'CuteEditor.Editor+a+a+c+a+a.a()' to access m ...

  9. Java 集合系列13之 TreeMap详细介绍(源码解析)和使用示例

    转载 http://www.cnblogs.com/skywang12345/p/3310928.html https://www.jianshu.com/p/454208905619

  10. [转]Navicat for oracle 提示 cannot load oci dll,193的解决方法 orcale 11g

    Navicat for oracle 提示 cannot load oci dll,193的解决方法   内网有一台windows server 2012,安装了Navicat 11.1.8 连接or ...