如何在ASP.Net Core中使用Scrutor

479 阅读4分钟

利用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 进行服务装饰的问题。