asp.net core拥有内置的DI,且只支持构造函数注入服务的形式,且只能逐条注册服务类型。
那么我们使用第三方的依赖注入框架,集成Autofac,拥有更强大的依赖注入功能。
2.在NuGet程序包,引入Autofac包,以及内置DI所需要的包
Autofac依赖注入:支持属性注入和构造注入。
3.在Program类中,集成Autofac
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Autofac.Extensions.DependencyInjection;
namespace WebApiApplication
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory());//使用Autofac服务提供工厂(强类型)--> 集成Autofac
}
}
4.在StartUp类中,添加ConfigureContainer方法:集成Autofac,配置容器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Autofac;
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 Microsoft.Extensions.Hosting;
using WebApiApplication.Controllers;
using WebApiApplication.Services;
namespace WebApiApplication
{
public class Startup
{
public IConfiguration _configuration;
public Startup(IConfiguration configuration) {
_configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
//AddControllersAsServices支持属性注入
//1.从容器中获取控制器实例
//2.将Asp.Net Core能发现的控制器类型都注册到容器中
services.AddControllers().AddControllersAsServices();
//services.AddControllers();
services.AddTransient<IAccount,Account>();
}
//配置容器的方法--> 集成Autofac -->由框架自动去调用
public void ConfigureContainer(ContainerBuilder builder)
{
//Autofac支持批量注册服务(.net core内置的DI不支持, 只能一个一个的注册)
//程序集扫描注入
var assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => t.Namespace == assembly.GetName().Name + ".Services")
.AsImplementedInterfaces().InstancePerLifetimeScope();
//给程序集下所有的控制器开启属性注入服务的功能
builder.RegisterAssemblyTypes(assembly)
.Where(t => typeof(ControllerBase).IsAssignableFrom(t) && t != typeof(ControllerBase))
.PropertiesAutowired();
//给指定的控制器开启属性注入服务的功能
builder.RegisterType<MessageController>().PropertiesAutowired();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
5.添加控制器,测试属性注入、构造注入:
注意:必须为publish属性
添加Service:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApiApplication.Services
{
public class Services
{
}
public interface IAccount { }
public interface ITool { }
public interface IMessage
{
public string Text { get; set; }
}
public class Account : IAccount { }
public class Message : IMessage
{
public string Text { get; set;}
public Message() {
Text = "Hello Message";
}
}
public class Tool : ITool { }
}
控制器类:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WebApiApplication.Services;
namespace WebApiApplication.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class MessageController:ControllerBase
{
public IMessage message { get; set;}
private readonly IMessage _message;
public MessageController(IMessage message) {
_message = message;
}
[HttpGet("Message")]
public IActionResult Get() {
return Ok(message.Text);
}
}
}
我们在ConfigureContainer方法中,去注册所有的服务,如果项目特别复杂时,不利于后期的维护。
AutoFac模块化管理:模块化的去注册服务,或者管理一些配置信息等等,有助于后期的维护
下面就来封装自己的服务,服务类必须继承Autofac.Module类
服务1:ControllerMoudle
using Autofac;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
/***
* AutoFac模块化管理:模块化的去注册服务,或者管理一些配置信息等等,有助于后期的维护
* 不同的模块,去处理不同的服务
*
*/
namespace WebApiApplication
{
public class ControllerMoudle : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
var containerBaseType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => containerBaseType.IsAssignableFrom(t) && t != containerBaseType)
.PropertiesAutowired();
}
}
}
服务2:ServiceMoudle
using Autofac;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
/***
* AutoFac模块化管理:模块化的去注册服务,或者管理一些配置信息等等,有助于后期的维护
*
*/
namespace WebApiApplication
{
public class ServiceMoudle : Autofac.Module
{
private readonly string _name;
public ServiceMoudle(string name) {
_name = name;
}
protected override void Load(ContainerBuilder builder)
{
var assembly= Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.Where(t => t.Namespace == $"{assembly.GetName().Name}.{_name}" )
.AsImplementedInterfaces().InstancePerLifetimeScope();
}
}
}
然后修改StartUp类中的ConfigureContainer方法:
public void ConfigureServices(IServiceCollection services)
{
//AddControllersAsServices支持属性注入
//1.从容器中获取控制器实例
//2.将Asp.Net Core能发现的控制器类型都注册到容器中
services.AddControllers().AddControllersAsServices();
//services.AddControllers();
services.AddTransient<IAccount,Account>();
}
//配置容器的方法--> 集成Autofac -->由框架自动去调用
public void ConfigureContainer(ContainerBuilder builder)
{
//使用模块化注册服务
builder.RegisterModule<ControllerMoudle>();
builder.RegisterModule(new ServiceMoudle(name: "Services"));
}