Aufofac在Core控制台中的使用

本文最后更新于:2021年9月29日 下午

引言

首先声明,本文使用的.NetCore版本是3.0以上,有使用后感觉不一致的同学请首先检查自己的版本问题。

场景说明:

NetCore的很多轮子和案例是基于NetCoreWeb的,毕竟Web的应用场景比较多,所以网上的文章也会多一些。
在NetCoreWeb中有我们熟知的Startup.cs 文件,其中有俩个重要的方法

1
2
3
4
public void ConfigureServices(IServiceCollection services)
{
//注册其他库提供的扩展方法
}
1
2
3
4
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//注册管道事件
}

相信大家看到这俩个方法会觉得倍感亲切,通过几个例子来让大家回忆加快

1
2
services.AddControllers() //控制器服务
services.AddCorsAccessor()//跨域服务

如果要注入自定义的类,我们可以通过以下三种方式

1
2
3
services.AddScoped();//请求作用域
services.AddTransient();//瞬时
services.AddSingleton();//单例

上文的内容相信大家看一下也就都了解了。

那么问题来了,有些应用我们不想弄web项目,太大太杂。我就想整一个控制台项目,用到什么添加什么。那这个时候我们如何利用依赖注入来实现和上文一样的效果呢?

控制台应用

core版本3.0以上,在此重申一下。

默认依赖注入

其实我们仔细看NetCoreWeb的初始项目可以发现,在Program.cs下Main方法可以看到了个初始执行函数。

1
2
3
4
5
6
7
8
9
10
11
12
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
});

Host.CreateDefaultBuilder其实就是在构造一个Host主机,自定义的内容使用StartUp中的俩个方法进行配置,最后.Run生成一个新的主机实例,就是一个服务 。

那么在控制台下有没有相似的方式 ,答案是有的。上代码

1
2
3
4
var builder = new HostBuilder()
.ConfigureServices((context, services) => { });

await builder.RunConsoleAsync();

new HostBuilder() Host.CreateDefaultBuilder() 这俩个方法是不是感觉是一样的,只是表现形式不一样,没错,你猜对了。

通过上文的方式就可以在控制台项目中创建一个host主机,ConfigureServices也可以正常使用,也可以点出自己需要的内容,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var builder = new HostBuilder()
.ConfigureAppConfiguration((context, config) =>
{
var env = context.HostingEnvironment;
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
.ConfigureLogging(loggerFactory =>
{
loggerFactory.ClearProviders();

//日志使用NLog
loggerFactory.AddNLog();
})

使用第三方依赖注入库如何集成

第三方库选择Autofac,相信大家都没有意见吧。:happy:

有些时候我们会有一些自己定制化的注入规则,例如按照某个特性标签才注入,某些前缀,某些后缀注入,使用接口方式注入。这些规则如果用自带api实现就会很不舒服,所有使用Autofac。

如何将Autofac继承Core控制台,我是真的找了好多文章才找到一个有用的,然后通过自己的实践测试发现可靠,特此分享给大家。

1、Nuget引入 Autofac.Extensions.DependencyInjection 包

1
nuget install  Autofac.Extensions.DependencyInjection

2、替换默认依赖注入工厂

1
.UseServiceProviderFactory(new AutofacServiceProviderFactory())

3、使用Autofac服务

1
2
3
4
.ConfigureServices((context, services) =>
{
services.AddAutofac();
}

4、配置自己的注入规则

1
2
3
4
5
6
7
8
9
10
.ConfigureContainer<ContainerBuilder>(builders =>
{
var IServices = Assembly.Load("Service.BLL");
builders.RegisterAssemblyTypes(IServices)
.Where(t => t.GetInterfaces().Contains(typeof(IDbBLL)))
.AsImplementedInterfaces()
.EnableInterfaceInterceptors();//接口注入实现

builders.RegisterType<RedisBLL>();//注入自定义类
})

5、整合测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var builder = new HostBuilder()
.ConfigureAppConfiguration((context, config) =>
{
var env = context.HostingEnvironment;
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory);
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builders =>
{
var IServices = Assembly.Load("Service.BLL");
builders.RegisterAssemblyTypes(IServices)
.Where(t => t.GetInterfaces().Contains(typeof(IDbBLL)))
.AsImplementedInterfaces()
.EnableInterfaceInterceptors();
})
.ConfigureServices((context, services) =>
{
services.AddAutofac();

//测试服务
//services.AddHostedService<DemoService>();
});

总结

通过文章的案例,相信大家对Autofac在控制台中的使用已经有了一个初步的理解,下面就是实践了。看的多不如做的多,不要让眼睛记住一,脑子还没记住。

参考

Asp.net Core依赖注入(Autofac替换IOC容器)


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!