前情提要:Asp.Net Core内置DI只支持构造函数契约模式接口抽象去推给容器让框架去注入实例化对象。
解释说明:我理解这其实是框架有意为之,目的就是为了让服务定位明确还有边界分明
如果使用服务定位模式(反模式)或者 属性注入,程序集注入,最大不同的一点就是 定位模糊,要么批量要么注入一个提供者自己在注册
服务定位模式(反模式)
生活示例: 我想吃鱼,告诉框架,给我鱼吃,然后内置DI 在容器先实例化一个 提供者极为鱼竿,然后用鱼竿钓鱼给到你。
服务定位模式就是,我想吃鱼,告诉框架,给我鱼竿我要钓鱼,然后容器IServiceCollection先实例化一个 提供者ServiceProvider 极为鱼竿给到我,然后我自己去钓鱼
对比:内置DI 明确吃鱼 直接把🐟给你 服务定位模式 只有个鱼竿 框架不知道你啥时候 有🐟 就模糊了
Autofac第三方依赖注入
第三方如何接入asp.net core中?
hosting里面托管了需要在后台长时间应用的服务,一个asp.net core 应用就是由一项Hosting托管的服务,依赖程序进程,一个Hosting可以托管多个asp.net core 应用,可以有多个Hosting,它其实也是一个对象。
Hosting采用依赖注入的方式来获取托管应用所需要的服务。
容器服务集合建立=》服务提供对象=》构建注入
与之对应的就是 第三方服务容器。第三方的服务提供对象
在内置DI中 容器服务集合IServiceCollection 只需要
services.AddScoped<ITest, TestImpl>();即可
步骤:
1.首先引用nuget包 以及在用到的地方添加所需引用
using Autofac;
using Autofac.Extensions.DependencyInjection;
using System.Reflection; //程序集
using TestServiceImpl; //测试用的写的 接口 方法
2.在StartUp类中建立autofac的 ConfigureContainer 方法
也就是替代IServiceCollection 的用处
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) //注册当前程序集
.As(t => t.GetInterfaces()[0]) //所有的接口类暴露出第一个 也就是 为什么我们规范 一个接口 对应一个实现就是为了好找
.InstancePerLifetimeScope(); //生命周期设置一下 scope作用域
}
虽然是替代IServiceCollection 的 但是毕竟不是内置的,写个方法还得要主机去声明
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(new AutofacServiceProviderFactory());
这样主机设置了使用autofac,主机启动时就会去识别第三方写的ConfigureContainer方法来达到实现代码实现注入
Autofac很强大,有时并不是用到很多功能,所以这里只是简单介绍了在哪个地方用,如果想ConfigureContainer方法特别丰富功能的话也可以参考官方文档,也是很简单上手的。
scrutor 一个依赖注入扩展
为什么使用?
内置DI 注册的时候 只能一个个的 ,太费事了
services.AddScoped<ITest, TestImpl>();
怎么使用?使用很简单
1:nuget包装一下
using Scrutor;
2:直接在ConfigureServices 去注册
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//services.AddScoped<ITest, TestImpl>();
services.Scan(scan => scan
.FromAssemblyOf<Startup>() //表示加载Startup这个类所在的程序集
//.AddClasses() //注册所有类
.AddClasses(classes => classes.Where(t => t.Name.EndsWith("test", StringComparison.OrdinalIgnoreCase))) //过滤一下注册的类
.UsingRegistrationStrategy(RegistrationStrategy.Skip) //策略 比如程序集注册重复的就跳过
//.AsMatchingInterface() //命名规则是 ITest/Test
.AsImplementedInterfaces()//命名规则不要求 可以是ITest/TestImpl
.WithTransientLifetime() //生命周期
);
}
具体详细文章 用Scrutor来简化ASP.NET Core的DI注册