首先,现有的三层项目的结构

其中  Repository

 public interface IPersonRepository
{
string Eat();
}
public class PersonRepository : IPersonRepository
{
public string Eat()
{
return "吃饭";
}
}

Service

public interface IPersonService
{
string Eat();
}
 public class PersonService : IPersonService
{
private IPersonRepository _personRespository;
//通过构造函数注入 repository
public PersonService(IPersonRepository personRespository)
{
_personRespository = personRespository;
}
public string Eat()
{
return _personRespository.Eat();
}
}

一、安装Autofac

nuget上安装Autofac

二、替换内置的DI框架

    将Startup.cs中的ConfigureServices返回类型改为IServiceProvider,然后新起一个方法RegisterAutofac把创建容器的代码放到其中,然后建一个AutofacModuleRegister类继承Autofac的Module,然后重写Module的Load方法 来存放新组件的注入代码,避免Startup.cs文件代码过多混乱。

 public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
return RegisterAutofac(services);//注册Autofac
}
 private IServiceProvider RegisterAutofac(IServiceCollection services)
{
//实例化Autofac容器
var builder = new ContainerBuilder();
//将Services中的服务填充到Autofac中
builder.Populate(services);
//新模块组件注册
builder.RegisterModule<AutofacModuleRegister>();
//创建容器
var Container = builder.Build();
//第三方IOC接管 core内置DI容器
return new AutofacServiceProvider(Container);
}
 public class AutofacModuleRegister:Autofac.Module
{
//重写Autofac管道Load方法,在这里注册注入
protected override void Load(ContainerBuilder builder)
{
//注册Service中的对象,Service中的类要以Service结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
}
/// <summary>
/// 根据程序集名称获取程序集
/// </summary>
/// <param name="AssemblyName">程序集名称</param>
/// <returns></returns>
public static Assembly GetAssemblyByName(String AssemblyName)
{
return Assembly.Load(AssemblyName);
}
}

此时Autofac基本使用已经配好了。

三、测试效果

修改HomeController 实现注入Service

 public class HomeController : Controller
{
private IPersonService _personService; //通过构造函数注入Service
public HomeController(IPersonService personService)
{
_personService = personService;
}
public IActionResult Index()
{
ViewBag.eat = _personService.Eat();
return View();
}
}

页面结果:

四、一个接口多个实现的情况

   比喻我现在在Service 中建三个类,IPayService, WxPayService,AliPayService,其中WxPayService,AliPayService都实现接口IPayService。

 public interface IPayService
{
string Pay();
}
public class AliPayService : IPayService
{
public string Pay()
{
return "支付宝支付";
}
}
 public class WxPayService : IPayService
{
public string Pay()
{
return "微信支付";
}
}

先试一下结果,修改HomeController

 public class HomeController : Controller
{
private IPersonService _personService;
private IPayService _payService; //通过构造函数注入Service
public HomeController(IPersonService personService,IPayService payService)
{
_personService = personService;
_payService = payService;
}
public IActionResult Index()
{
ViewBag.eat = _personService.Eat();
ViewBag.pay = _payService.Pay();
return View();
}
}

View

@{
ViewData["Title"] = "Home Page";
}
@ViewBag.eat <br />
@ViewBag.pay

输出页面:

最后得到的是微信支付,因为两个对象实现一个接口的时候,注册时后面注册的会覆盖前面注册的。如果我想得到支付宝支付要怎么做呢?

 我们可以用另外一种注册方式RegisterType,修改注册方式AutofacModuleRegister.cs。

 public class AutofacModuleRegister:Autofac.Module
{
//重写Autofac管道Load方法,在这里注册注入
protected override void Load(ContainerBuilder builder)
{
//注册Service中的对象,Service中的类要以Service结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
//注册Repository中的对象,Repository中的类要以Repository结尾,否则注册失败
builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();
//单独注册
builder.RegisterType<WxPayService>().Named<IPayService>(typeof(WxPayService).Name);
builder.RegisterType<AliPayService>().Named<IPayService>(typeof(AliPayService).Name);
}
/// <summary>
/// 根据程序集名称获取程序集
/// </summary>
/// <param name="AssemblyName">程序集名称</param>
/// <returns></returns>
public static Assembly GetAssemblyByName(String AssemblyName)
{
return Assembly.Load(AssemblyName);
}
}

用Named区分两个组件的不同,后面的typeof(WxPayService).Name 是任意字符串,这里直接用这个类名作标识,方便取出来时也是用这个名字,不易忘记。

然后就是取出对应的组件了,取的时候用Autofac的 上下文(IComponentContext) ,修改HomeController

 public class HomeController : Controller
{
private IPersonService _personService;
private IPayService _wxPayService;
private IPayService _aliPayService;
private IComponentContext _componentContext;//Autofac上下文
//通过构造函数注入Service
public HomeController(IPersonService personService, IComponentContext componentContext)
{
_personService = personService;
_componentContext = componentContext;
//解释组件
_wxPayService = _componentContext.ResolveNamed<IPayService>(typeof(WxPayService).Name);
_aliPayService =_componentContext.ResolveNamed<IPayService>(typeof(AliPayService).Name);
}
public IActionResult Index()
{
ViewBag.eat = _personService.Eat();
ViewBag.wxPay = _wxPayService.Pay();
ViewBag.aliPay = _aliPayService.Pay();
return View();
}
}

Index View:

@{
ViewData["Title"] = "Home Page";
}
@ViewBag.eat <br />
@ViewBag.wxPay <br />
@ViewBag.aliPay

结果:

完成。

    

最新文章

  1. 将list中的数据通过某一个字段来分类存储的实例
  2. vim学习
  3. nsq初探
  4. How does Spring @Transactional Really Work?--转
  5. python关键字,运算符
  6. asp+mysql__不同类型用户登录
  7. MySQL学习笔记--数据类型
  8. OpenCV C++ 计算文件夹中对象文件数目及批量处理后保存到txt文件
  9. oracle视图如何使用
  10. GlusterFS创建volume失败的解决方法(* or a prefix of it is already part of a volume)
  11. (转)数据库 distinct 和 group by 的区别
  12. JS封装运动框架(另一种写法)
  13. java乱码解决方法
  14. js实现下雪雪花特效
  15. web(七)css的语法规则、注释
  16. linux下vscode的c++工程配置
  17. MySQL 5.7的原生JSON数据类型使用
  18. .NET 切面编程 PostSharp
  19. 【mongodb】Mongodb初识
  20. iOS中的数据存储方式_SQLite3

热门文章

  1. MyBatis之分页插件(PageHelper)工作原理
  2. springboot(五)过滤器和拦截器
  3. webpack4.0各个击破(6)—— Loader篇
  4. .Net语言 APP开发平台——Smobiler学习日志:HoverBackColor属性的简单介绍
  5. [android]android项目的目录结构
  6. Android项目刮刮奖详解扩展篇——开源刮刮奖View的制作
  7. Axure rp8团队原型图开发
  8. 【20190407】JavaScript-indexOf方法解析
  9. Dynamics Customer Engagement V9版本配置面向Internet的部署时候下一步按钮不可点击的解决办法
  10. 转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案