原文地址:https://www.cnblogs.com/Andre/p/9604759.html

初识ASP.NET Core的小伙伴一定会发现,其几乎所有的项目依赖都是通过依赖注入方式进行链式串通的。这是因为其使用了依赖注入 (DI) 的软件设计模式,代码的设计是遵循着“高内聚、低耦合”的原则,使得各个类与类之间的关系依赖于接口,这样做的目的是能更有利于项目代码的维护与扩展。

Autofac

在进入主题之前咱们还是先来简单的认识下鼎鼎大名的“Autofac”吧。那么何为Autofac呢,通俗的讲就是一个开源的,且基于.NET Core、ASP.NET Core、.NET 4.5.1+等框架实现的控制反转(IOC)类库。通过Autofac可以在.NET Core、ASP.NET Core、.NET 4.5.1+等项目上很容易的实现依赖注入,代码很容易就能达到“高内聚、低耦合”的原则。另外,Autofac的中文资料也很多,需要详细了解的也可在网上自行查看。

Autofac官方网站:https://autofac.org/

Autofac官方的中文文档网站:https://autofaccn.readthedocs.io/zh/latest/

 

背景

在我们大部分的项目中都会将代码抽成多层,每层之间通过相互依赖串联工作。在这里,我们将ASP.NET Core项目代码抽成三层结构,分别为输入输出层(MVC项目)、业务层(类库)、数据层(类库),每层的功能描述如下:

1、Lezhima.Web:接受来自客户端的请求,及服务端响应的出入口。由一个基于ASP.NET Core的MVC项目组成。

2、Lezhima.Core:根据请求做出相应的业务判断,及调度上下游数据并计算,输出相应的业务结果给调用者。由一个基于.NET Core的类库组成。

3、Lezhima.Data:直接跟DB进行通讯交互,实现对DB的增、删、改、查等操作。由一个基于.NET Core的类库组成。

依赖关系:

基于上述中的三层代码结构,我们可以清晰的看出Lezhima.Web做为项目出入口,在其需要时会调用Lezhima.Core类库,并将业务交由Lezhima.Core库处理,而Lezhima.Core类库在其需要时会调用Lezhima.Data类库操作DB。那么,它们之间的依懒关系应该是这样子的:

1、Lezhima.Web同时依赖于Lezhima.Core与Lezhima.Data类库。

2、Lezhima.Core依赖于Lezhima.Data类库。

实现代码

通过上面的介绍,我们清楚了三个分层之间的功能与依赖关系,那么接下来我们就分别来看看它们具体代码及使用Autofac如何优雅的实现依赖注入吧。

1、首先在Lezhima.Web项目中通过NuGet管理器引用:Autofac、Autofac.Extensions.DependencyInjection两个类库。

2、我们先来看看Lezhima.Data层的代码,首先定义一个名为“IRepository”接口,代码如下:

  1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Linq;
5 using System.Linq.Expressions;
6 using System.Text;
7 using System.Threading.Tasks;
8
9 namespace Lezhima.Data.Interface
10 {
11 public interface IRepository<T> where T : class
12 {
13 /// <summary>
14 /// 从指定的表中获取符合条件的一条实体数据
15 /// </summary>
16 /// <param name="predicate"></param>
17 /// <returns></returns>
18 Task<T> GetAsync(Expression<Func<T, bool>> predicate);
19 }
20 }

 

3、在Lezhima.Data层再增加一个名为“Repository”类,实现“IRepository”接口,代码如下:

  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Data;
7 using System.Linq.Expressions;
8 using Microsoft.EntityFrameworkCore;
9 using System.Data.SqlClient;
10 using Lezhima.Data.Interface;
11
12 namespace Lezhima.Data
13 {
14 /// <summary>
15 /// 数据层
16 /// 实现IRepository接口
17 /// </summary>
18 /// <typeparam name="T"></typeparam>
19 public class Repository<T> : IRepository<T> where T : class
20 {
21
22 /// <summary>
23 /// 从指定的表中获取符合条件的一条实体数据
24 /// </summary>
25 /// <param name="predicate"></param>
26 /// <returns></returns>
27 public async Task<T> GetAsync(Expression<Func<T, bool>> predicate)
28 {
29 using (var db = new LezhimaContext())
30 {
31 if (predicate == null)
32 return null;
33
34 return await db.Set<T>().Where(predicate).FirstOrDefaultAsync<T>();
35 }
36 }
37 }
38 }
39

 

4、在Lezhima.Core层再定义一个名为“IUserCore”接口,代码如下:

  1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Threading.Tasks;
5
6 namespace Lezhima.Core.Interface
7 {
8 public interface IUserCore
9 {
10 /// <summary>
11 /// 根据账号密码判断用户是否拥有合法登录权限
12 /// </summary>
13 /// <param name="email"></param>
14 /// <returns>100成功,101账号错误,102密码错误,103参数不合法</returns>
15 Task<MobiResult> Login(string email,string pwd);
16 }
17 }
18

5、在Lezhima.Core层再增加一个名为“UserCore”类,实现“IUserCore”接口,代码如下:

  1 using Lezhima.Core.Interface;
2 using Lezhima.Data.Interface;
3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace Lezhima.Core
9 {
10 public class UserCore : IUserCore
11 {
12 //定义一个依赖属性
13 private readonly IRepository<EB_User> _Repository;
14
15 /// <summary>
16 /// 通过构造涵数方式注入Data层的Repository实例
17 /// </summary>
18 /// <param name="repository"></param>
19 public UserCore(IRepository<EB_User> repository)
20 {
21 _Repository = repository;
22 }
23
24
25 /// <summary>
26 /// 根据账号密码判断用户是否拥有合法登录权限
27 /// </summary>
28 /// <returns>100成功,101账号错误,102密码错误,103参数不合法</returns>
29 public async Task<MobiResult> Login(string email, string pwd)
30 {
31 if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(pwd))
32 return new MobiResult(103);
33
34 //到Data层去取指定用户的数据
35 var model= await _Repository.GetAsync(p => p.Email.Equals(email)&&p.IsDelete!=99);
36 if(model ==null)
37 return new MobiResult(101);
38
39 if(!model.Pwd.Equals(pwd))
40 return new MobiResult(102);
41
42 return new MobiResult(100);
43 }
44
45 }
46 }
47

6、在Lezhima.Web层增加一个名为“AccountController ”的控制器,代码如下:

  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Security.Claims;
5 using System.Threading.Tasks;
6 using Lezhima.Core.Interface;
7 using Microsoft.AspNetCore.Authentication;
8 using Microsoft.AspNetCore.Authentication.Cookies;
9 using Microsoft.AspNetCore.Authorization;
10 using Microsoft.AspNetCore.Http;
11 using Microsoft.AspNetCore.Mvc;
12
13 namespace Lezhima.Web.Controllers
14 {
15 [Authorize]
16 [AutoValidateAntiforgeryToken]
17 public class AccountController : Controller
18 {
19
20 //定义一个依赖属性
21 private readonly IUserCore _UserCore;
22
23 /// <summary>
24 /// 通过构造涵数方式注入Core层的UserCore实例
25 /// </summary>
26 /// <param name="__UserCore"></param>
27 public AccountController(IUserCore __UserCore)
28 {
29 _UserCore = __UserCore;
30 }
31
32
33 // GET: Account
34 public ActionResult Index()
35 {
36 return View();
37 }
38
39
40
41
42 /// <summary>
43 /// 实现客户端的登录操作
44 /// </summary>
45 /// <param name="loginRequest"></param>
46 /// <returns></returns>
47 [HttpPost]
48 [AllowAnonymous]
49 public async Task<IActionResult> Login(LoginRequest loginRequest)
50 {
51 var result = await _UserCore.Login(loginRequest.Email, loginRequest.Pwd);
52
53 if (result.Code != 100)
54 {
55 ViewBag.ResultModel = result;
56 return View();
57 }
58
59 //向客户端写入用户的身份cookie
60 var _user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
61 {
62 new Claim("UserId", user_model.UserId.ToString()),
63 }, CookieAuthenticationDefaults.AuthenticationScheme));
64 await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, _user);
65
66 if (string.IsNullOrWhiteSpace(loginRequest.ReturnUrl))
67 {
68 return RedirectToAction("Index", "Home");
69 }
70 return Redirect(loginRequest.ReturnUrl);
71 }
72
73 }
74 }

7、在Lezhima.Web层增加一个名为“Evolution”的类,用于继承Autofac的Module类,实现上述三层之间的依赖关系注入,代码如下:

  1 using Autofac;
2 using Lezhima.Core;
3 using Lezhima.Data;
4 using Lezhima.Data.Interface;
5 using System;
6
7 namespace Lezhima.Web.Injection
8 {
9 /// <summary>
10 /// 重写依赖注入的业务
11 /// </summary>
12 public class Evolution : Module
13 {
14 protected override void Load(ContainerBuilder builder)
15 {
16 //注入Data层的Repository类
17 builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerDependency();
18 //批量注入Core层的类
19 builder.RegisterAssemblyTypes(typeof(UserCore).Assembly)
20 .Where(t => t.Name.EndsWith("Core"))
21 .AsImplementedInterfaces();
22 }
23 }
24 }
25

8、在Lezhima.Web层的“Startup”类的“ConfigureServices”方法内注入即可,代码如下:

  1 public IConfiguration Configuration { get; }
2
3 public IServiceProvider ConfigureServices(IServiceCollection services)
4 {
5 services.AddMvc();
6
7 //将Evolution注册到项目中来,实现依赖注入
8 var builder = new ContainerBuilder();
9 builder.RegisterModule(new Evolution());
10 builder.Populate(services);
11 var container = builder.Build();
12 return container.Resolve<IServiceProvider>();
13 }

  

总结

1、每层在调用时,通过在该类内声明一个接口类型的属性(变量),再通过Autofac构造涵数注入方式实现依赖注入并获取到相应的类实例。

2、通过继承Autofac的Module类,并在Load方法内重写自已项目的类关系来实现注入业务。

3、Autofac注入有多种不同的生命周期类型,分别为InstancePerLifetimeScope、SingleInstance、InstancePerDependency等,各位在项目中按需选择即可。

4、最后再通过在ASP.NET Core项目内的“Startup”类内将注入代码类注册到项目中就可正常使用了。

ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便(转载)的更多相关文章

  1. ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便

    初识ASP.NET Core的小伙伴一定会发现,其几乎所有的项目依赖都是通过依赖注入方式进行链式串通的.这是因为其使用了依赖注入 (DI) 的软件设计模式,代码的设计是遵循着“高内聚.低耦合”的原则, ...

  2. ASP.NET MVC IOC依赖注入之Autofac系列(二)- WebForm当中应用

    上一章主要介绍了Autofac在MVC当中的具体应用,本章将继续简单的介绍下Autofac在普通的WebForm当中的使用. PS:目前本人还不知道WebForm页面的构造函数要如何注入,以下在Web ...

  3. ASP.NET MVC IOC依赖注入之Autofac系列(一)- MVC当中应用

    话不多说,直入主题看我们的解决方案结构: 分别对上面的工程进行简单的说明: 1.TianYa.DotNetShare.Model:为demo的实体层 2.TianYa.DotNetShare.Repo ...

  4. .NET领域最为流行的IOC框架之一Autofac WebAPI2使用Autofac实现IOC属性注入完美解决方案 AutoFac容器初步

    .NET领域最为流行的IOC框架之一Autofac   一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程 ...

  5. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  6. IOC依赖注入简单实例

    转自:http://hi.baidu.com/xyz136299110/item/a32be4269e9d0c55c38d59e6 相信大家看过相当多的IOC依赖注入的例子. 但大家在没有明白原理的情 ...

  7. IoC 依赖注入容器 Unity

    原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...

  8. springboot启动流程(九)ioc依赖注入

    所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 在前面的几篇文章中,我们多次提到这么一个转化过程: Bean配置 --> Bean ...

  9. Spring-DI控制反转和IOC依赖注入

    Spring-DI控制反转和IOC依赖注入 DI控制反转实例 IDEAJ自动导入Spring框架 创建UserDao.java接口 public interface UserDao { public ...

随机推荐

  1. Serverless 的喧哗与骚动(一)附Serverless行业发展回顾

    作者 | 阿里中间件高级技术专家 许晓斌 <Maven实战>作者,曾负责 AliExpress 微服务架构演进,现在负责阿里集团 Serverless 技术研发落地. 导读:从 2016 ...

  2. PHP--常用配置项

    一.简介 PHP的配置项可以在配置文件php.ini中配置,也可以在脚本中使用ini_set()函数临时配置. 二.常用配置项 1.错误信息相关配置 1)display_errors 设定PHP是否将 ...

  3. jakarta-oro-2.0.8.jar-----------JAVA FTP相关

    资源不好找,找到了就和大家分享一下! 链接:https://share.weiyun.com/51kBB0y 密码:2hcxcu

  4. Winform中设置ZedGraph鼠标滚轮缩放的灵敏度以及设置滚轮缩放的方式(鼠标焦点为中心还是图形中心点)

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  5. mysql报错com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException

    一.问题 运行java代码时报如下的错误: You have an error in your SQL syntax;Cause:com.mysql.jdbc.exceptions.jdbc4.MyS ...

  6. 轻量级手绘软件openCanvas免费版,手绘板CG手绘软件

    轻量级手绘软件openCanvas免费版,手绘板CG手绘软件 手绘软件通俗一点来说就是用手来绘画的软件,应用很宽泛如建筑,服饰陈列设计.橱窗设计.家居软装设计.空间花艺设计.美术.园林.环艺.摄影.工 ...

  7. CTF必备技能丨Linux Pwn入门教程——ROP技术(下)

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  8. PMP备考-第一章-引论

    项目 项目是为创造独特的产品,服务和成果而进行的临时性工作.在规定的范围,进度,成本,和质量要求之下完成项目可交付成果. 项目与运用 项目 :临时性,独特性,渐进明细 运营 :持续的,相似性,标准化 ...

  9. ES6的export与Nodejs的module.exports比较

    首先我们要明白一个前提,CommonJS模块规范和ES6模块规范完全是两种不同的概念. CommonJS模块规范 Node应用由模块组成,采用CommonJS模块规范. 根据这个规范,每个文件就是一个 ...

  10. MySQL详细安装(windows)

    一.在MySQL官网上下载MySQL Community Server(目前推荐5.7版本,8.0版本在安装的时候遇到的问题比较多) 点击DOWNLOADS→Community→MySQL Commu ...