利用Scrutor消除繁琐的样板配置,无需在ASP.Net Core中注册服务。
依赖注入 (DI) 可促进松散耦合,促进可测试性和维护。你可以利用依赖注入来更改实现,而无需更改利用这些实现的类或接口。依赖注入是软件架构的 SOLID 原则之一。它用于将对象的使用与对象的构造方式脱钩。
如果没有依赖注入,如果对象的任何依赖发生变化,则必须对其进行修改。如果没有依赖注入,则很难对具有附属对象的对象进行单元测试。通过依赖注入,对象不会在内部构建其依赖对象:相反,依赖对象是在运行时注入的。
依赖注入是ASP.Net Core的重要组成部分。但是,按照设计,ASP.Net Core只包括一个功能最小、功能最少的简单 DI 容器,其他高级功能将留给第三方来扩展。Scrutor是一个开源库,为ASP.Net Core DI 容器添加程序集扫描功能。本文探讨了我们如何在ASP.Net Core中使用Scrutor。
请务必注意,Scrutor不是 DI 容器。相反,Scrutor 提供了一个流利的 API,使用内置的 ASP.NET Core DI 容器,根据约定注册服务。如果你需要一个具有更多功能和功能的 DI 容器,你可以使用第三方 DI 容器,如AutoFac,Windsor,StructureMap,Ninject和DryIoc。Scrutor 可用于在ASP.Net Core中提供程序集扫描和装饰扩展。
创建ASP.Net Core Web API 项目
在本节中,我们将创建一个ASP.Net Core应用程序,并用它来了解我们如何使用 Scrutor。按照下面列出的步骤,在Visual Studio 2017 中创建新的ASP.Net Core项目。
- 启动Visual Studio 2017 IDE.
- 单击文件>新建>项目。
- 选择"ASP.Net CoreWeb应用程序"项目模板。
- 指定项目名称和位置。
- 点击"确定"。
- 在"新ASP.Net CoreWeb应用程序"对话窗口中,选择.Net Core。
- 选择ASP.Net Core 2.1 作为项目的版本。
- 选择"Web API"作为项目模板。
- 取消选中"启用Docker支持"和"配置HTTPS"复选框:我们不会在这里使用这些功能。
- 确保显示"无身份验证"消息:我们也不需要身份验证。
- 点击"确定"。
这将在Visual Studio中创建一个新的ASP.Net Core项目。接下来,使用 NuGet 包管理器或 NuGet 控制台从 NuGet 安装Scrutor。截至本文撰写时,最新版本的 Scrutor 为 3.0.2。
在ASP.Net Core中使用 Scrutor 扫描程序集
Scrutor API有两种扩展方法——扫描和装饰——它们扩展IServiceCollection接口的功能。扫描用于在程序集中搜索与要注册的服务相对应的类型,装饰用于装饰服务实例。在这篇文章中,我们将研究扫描方法。我将在这里稍后的帖子中说明我们如何使用装饰方法。
使用扫描方法时,可以定义选择器、注册策略、服务和服务的生命周期。选择器用于指定如何在程序集中定位服务。Scrutor 扫描程序集中的类型,搜索与约定相匹配的类型,然后将其注册到ASP.Net Core的内置 DI 容器中。
让我们以一个例子来理解这一点。假设你必须注册三项服务,即 IService1、IService2 和 IService3。让相应的服务实现在名为"Service1"、"Service2"和"Service3"的类中。如果没有 Scrutor,则通常需要编写一些代码才能注册这些服务,代码如下。
services.AddScoped<IService1, Service1>();
services.AddScoped<IService2, Service2>();
services.AddScoped<IService3, Service3>();
在ASP.Net Core中使用 Scrutor 注册服务
以下代码片段说明了如何利用 Scrutor 的程序集扫描功能,以大大简化的方式在Startup类的ConfigureServices方法中注册这些服务。
public void ConfigureServices(IServiceCollection services)
{
services.Scan(scan =>
scan.FromCallingAssembly()
.AddClasses()
.AsMatchingInterface());
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
你还可以在扫描方法中显式指定类型。假设你有两个服务,ServiceA和ServiceB。以下代码片段说明了你如何将这些服务注册为临时服务。
services.AddTransient<ServiceA>();
services.AddTransient<ServiceB>();
以下代码片段说明了如何显式指定扫描方法中的类型,并以瞬时生存期注册这两个服务。
services.Scan(scan => scan
.AddTypes<ServiceA, ServiceB>()
.AsSelf()
.WithTransientLifetime());
在扫描方法的另一个变体中,你可以显式传递该类型,并让 Scrutor 在该类型的程序集中找到所有类。下面是一个说明这一点的例子。
services.Scan(scan => scan
.FromAssemblyOf<IDataService>()
.AddClasses()
.AsSelf()
.WithTransientLifetime());
Scrutor 是一个开源框架,它为默认的 Microsoft.Extensions.DependencyInjection DI容器在ASP.Net Core中增加了扫描功能。它还可以提供服务装饰功能。我将在这里稍后的帖子中讨论使用 Scrutor 进行服务装饰的问题。