在上一章中主要和大家分享了在ASP.NET Core中如何使用Autofac替换自带DI进行构造函数的批量依赖注入,本章将和大家继续分享如何使之能够同时支持属性的批量依赖注入。
1、仓储层接口都以“I”开头,以“Repository”结尾。仓储层实现都以“Repository”结尾。
2、服务层接口都以“I”开头,以“Service”结尾。服务层实现都以“Service”结尾。
接下来我们正式进入主题,在上一章的基础上我们再添加一个web项目TianYa.DotNetShare.CoreAutofacDemo,首先来看一下我们的解决方案
本demo的web项目为ASP.NET Core Web 应用程序(.NET Core 2.2) MVC框架,需要引用以下几个程序集:
1、TianYa.DotNetShare.Model 我们的实体层
2、TianYa.DotNetShare.Service 我们的服务层
3、TianYa.DotNetShare.Repository 我们的仓储层,
正常我们的web项目是不应该使用仓储层的,此处我们引用是为了演示IOC依赖注入
4、Autofac 依赖注入基础组件
5、Autofac.Extensions.DependencyInjection 依赖注入.NET Core的辅助组件
其中Autofac和Autofac.Extensions.DependencyInjection需要从我们的NuGet上引用,依次点击下载以下2个包:
接着我们在web项目中添加一个类AutofacModuleRegister.cs用来注册Autofac模块,如下所示:
///
重写Autofac管道Load方法,在这里注册注入
///
</summary>
protected
override
void
Load(ContainerBuilder builder)
//
builder.RegisterType<StudentRepository>().As<IStudentRepository>().PropertiesAutowired()
//
.InstancePerLifetimeScope();
//
builder.RegisterType<StudentService>().As<IStudentService>().PropertiesAutowired()
//
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(GetAssemblyByName(
"
TianYa.DotNetShare.Repository
"
))
.Where(a
=> a.Name.EndsWith(
"
Repository
"
))
.AsSelf().AsImplementedInterfaces().PropertiesAutowired().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(GetAssemblyByName(
"
TianYa.DotNetShare.Service
"
))
.Where(a
=> a.Name.EndsWith(
"
Service
"
))
.AsSelf().AsImplementedInterfaces().PropertiesAutowired().InstancePerLifetimeScope();
//
注册MVC控制器,注册所有到控制器
var
controllersTypesInAssembly =
typeof
(Startup).Assembly.GetExportedTypes()
.Where(type
=>
typeof
(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
///
<summary>
///
根据程序集名称获取程序集
///
</summary>
///
<param name="assemblyName">
程序集名称
</param>
public
static
Assembly GetAssemblyByName(
string
assemblyName)
return
Assembly.Load(assemblyName);
using
System.Threading.Tasks;
using
Microsoft.AspNetCore.Builder;
using
Microsoft.AspNetCore.Hosting;
using
Microsoft.AspNetCore.Http;
using
Microsoft.AspNetCore.Mvc;
using
Microsoft.Extensions.Configuration;
using
Microsoft.Extensions.DependencyInjection;
using
Autofac;
using
Autofac.Extensions.DependencyInjection;
namespace
TianYa.DotNetShare.CoreAutofacDemo
public
class
Startup
public
Startup(IConfiguration configuration)
Configuration
=
configuration;
public
IConfiguration Configuration {
get
; }
//
This method gets called by the runtime. Use this method to add services to the container.
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_2).AddControllersAsServices();
return
RegisterAutofac(services);
//
注册Autofac
//
This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public
void
Configure(IApplicationBuilder app, IHostingEnvironment env)
if
(env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseExceptionHandler(
"
/Home/Error
"
);
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes
=>
routes.MapRoute(
name:
"
default
"
,
template:
"
{controller=Home}/{action=Index}/{id?}
"
);
///
<summary>
///
注册Autofac
///
</summary>
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);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).AddControllersAsServices();
接下来我们来看看控制器里面怎么弄:
using
System.Threading.Tasks;
using
Microsoft.AspNetCore.Mvc;
using
TianYa.DotNetShare.CoreAutofacDemo.Models;
using
TianYa.DotNetShare.Service;
using
TianYa.DotNetShare.Repository;
using
TianYa.DotNetShare.Repository.Impl;
namespace
TianYa.DotNetShare.CoreAutofacDemo.Controllers
public
class
HomeController : Controller
///
<summary>
///
定义仓储层学生抽象类对象
///
</summary>
private
IStudentRepository _stuRepository;
///
<summary>
///
定义服务层学生抽象类对象
///
</summary>
private
IStudentService _stuService;
///
<summary>
///
定义服务层学生抽象类对象
///
属性注入:访问修饰符必须为public,否则会注入失败。
///
</summary>
public
IStudentService StuService {
get
;
set
; }
///
<summary>
///
定义仓储层学生实现类对象
///
属性注入:访问修饰符必须为public,否则会注入失败。
///
</summary>
public
StudentRepository StuRepository {
get
;
set
; }
///
<summary>
///
通过构造函数进行注入
///
注意:参数是抽象类,而非实现类,因为已经在Startup.cs中将实现类映射给了抽象类
///
</summary>
///
<param name="stuRepository">
仓储层学生抽象类对象
</param>
///
<param name="stuService">
服务层学生抽象类对象
</param>
public
HomeController(IStudentRepository stuRepository, IStudentService stuService)
this
._stuRepository =
stuRepository;
this
._stuService =
stuService;
public
IActionResult Index()
var
stu1 = StuRepository.GetStuInfo(
"
10000
"
);
var
stu2 = StuService.GetStuInfo(
"
10001
"
);
var
stu3 = _stuService.GetStuInfo(
"
10002
"
);
var
stu4 = _stuRepository.GetStuInfo(
"
1003
"
);
string
msg = $
"
学号:10000,姓名:{stu1.Name},性别:{stu1.Sex},年龄:{stu1.Age}<br />
"
;
msg
+= $
"
学号:10001,姓名:{stu2.Name},性别:{stu2.Sex},年龄:{stu2.Age}<br/>
"
;
msg
+= $
"
学号:10002,姓名:{stu3.Name},性别:{stu3.Sex},年龄:{stu3.Age}<br/>
"
;
msg
+= $
"
学号:10003,姓名:{stu4.Name},性别:{stu4.Sex},年龄:{stu4.Age}<br/>
"
;
return
Content(msg,
"
text/html
"
, System.Text.Encoding.UTF8);
public
IActionResult Privacy()
return
View();
[ResponseCache(Duration
=
0
, Location = ResponseCacheLocation.None, NoStore =
true
)]
public
IActionResult Error()
return
View(
new
ErrorViewModel { RequestId = Activity.Current?.Id ??
HttpContext.TraceIdentifier });