2021-04-03 乐帮网
netcore autofac
.NET Core支持DI(依赖性注射) ,它可以实现设计模式中的控制反转(IoC)在类与其实现之间形成对应。原生、简约的实现已经为Net core中的一部分了。您可以从微软官方网站阅读更多有关它的介绍,在第三方DI框架中对它的支持也很好,对大多数小型项目项目来说,这已经足够好了。作为DI的资深用户,我们也应该掌握最前沿的 Autofac 6 与.Net Core的集成应用。
(1)Autofac的入门
public class Program
{
public static void Main(string[] args)
{
// ASP.NET Core 3.0+:
// The UseServiceProviderFactory call attaches the
// Autofac provider to the generic hosting mechanism.
var host = Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webHostBuilder => {
webHostBuilder
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>();
})
.Build();
host.Run();
}
}
public class Startup
{
public Startup(IHostingEnvironment env)
{
// In ASP.NET Core 3.0 `env` will be an IWebHostEnvironment, not IHostingEnvironment.
this.Configuration = new ConfigurationBuilder().Build();
}
public IConfigurationRoot Configuration { get; private set; }
public ILifetimeScope AutofacContainer { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
}
public void ConfigureContainer(ContainerBuilder builder)
{
// Register your own things directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory
// for you.
builder.RegisterModule(new MyApplicationModule());
}
public void Configure(
IApplicationBuilder app,
ILoggerFactory loggerFactory)
{
// If, for some reason, you need a reference to the built container, you
// can use the convenience extension method GetAutofacRoot.
this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
(2)从assemblies中注册服务
Autofac 可以直接扫描Assembly,然后把类型注册到容器当中。
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(typeof(Startup).Assembly)
.AsClosedTypesOf(typeof(IConfigureOptions<>));
}
这将注册给定类型的具体实现。 在这种情况下,它将注册IConfigureOptions <>的所有实现。 有关如何使用依赖项注入配置设置的更多信息,请参见选项模式。
(3)在Autofac中使用Mvc / Api控制器实例化
我们无法从容器中解析出控制器; 只能生成控制器中构造函数的参数。 这意味着在控制器的生命周期中,属性注入等不由Autofac管理,而是由ASP.NET Core管理。 您可以使用AddControllersAsServices()进行更改。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersAsServices();
}
public void ConfigureContainer(ContainerBuilder builder) {
var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
}
在这里,我们注册所有类型的控制器基础类型的父类,也就是处自定义Contoller类。我们还启用属性注入功能(第 5 行)。当您想要在基础控制器实现中拥有一些可以重复使用的属性时,这很有用。
(4)使用Autofac 注册 EF Core DbContext
如果使用Entity Framework Core,则希望DbContext由DI容器管理。 一个重要的注意事项是DbContext应该作为一个工作单元运行,并且可以请求生存期。 在本机DI中,它注册为范围服务,在Autofac中等于InstancePerLifetimeScope。
public static void AddCustomDbContext(this ContainerBuilder builder, IConfiguration configuration) {
builder.Register(c => {
var options = new DbContextOptionsBuilder<ApplicationContext>();
options.UseLoggerFactory(c.Resolve<ILoggerFactory>()).EnableSensitiveDataLogging();
options.UseSqlServer(configuration["ConnectionStrings:ApplicationDb"], sqlOptions => { sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name);
sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
});
return options.Options;
}).InstancePerLifetimeScope();
builder.RegisterType<ApplicationContext>()
.AsSelf()
.InstancePerLifetimeScope();
}
public void ConfigureContainer(ContainerBuilder builder) {
builder.AddCustomDbContext(this.Configuration);
}
(5)使用 modules来注册
public void ConfigureContainer(ContainerBuilder builder) {
builder.RegisterModule(new MediatorModule());
builder.RegisterModule(new ApplicationModule());
}
public class ApplicationModule: Autofac.Module {
public ApplicationModule() {}
protected override void Load(ContainerBuilder builder) {
builder.RegisterType<NinjaService>().As<INinjaService>().SingleInstance();
builder.RegisterType<KatanaService>().As<IKatanaService>().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly).AsClosedTypesOf(typeof(INinjaRepository<>)).InstancePerLifetimeScope();
}
}
在模块中或以按照你项目的结构来注册你的实例。
原文:https://danylomeister.blog/2021/01/31/tips-on-using-autofac-in-net-core-3-x/
关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com
庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。
如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力