前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Blazor 中的依赖项注入

Blazor 中的依赖项注入

作者头像
科控物联
发布2024-03-20 14:00:19
1210
发布2024-03-20 14:00:19
举报
文章被收录于专栏:科控自动化科控自动化

依赖注入 (DI) 是一种通过关注点分离来促进软件松散耦合的技术。在 Blazor 应用程序的上下文中,DI 鼓励你为特定任务开发离散服务,然后将这些服务注入到需要使用其功能的组件和类中。这些依赖类旨在调用针对抽象的操作,而不是针对特定的依赖项实现,从而确保使用类不绑定到特定的实现。这样可以使应用程序更易于维护和测试。

Blazor 中的服务

Razor 组件主要与 UI 表示有关。生成 UI 所涉及的部分工作通常涉及与数据存储进行通信,可能是通过 Web 服务。可能需要记录组件中的操作和事件。数据访问和日志记录不是 Razor 组件的主要关注点。执行日志记录或提取数据的代码不属于 UI 组件。在 Razor 组件中包含此类代码会违反单一原则。

调用 Web 服务或记录操作的代码应编写在单独的类(或多个类)中。这些类通常称为服务。这样做可以满足单一责任主体,但你仍然需要某种方式使这些服务可用于 Razor 组件。

您可以简单地在组件中实例化服务类:

代码语言:javascript
复制
@code{
    DataAccessService service; = new DataAccessService();
    List<Contact> contacts;

    protected void OnInitialized()
    {
        service = new DataAccessService();
        contacts = service.GetContacts();
    }
    ...
}

然而,这种方法会导致紧密耦合。Razor 组件与数据访问服务的特定实现紧密耦合。由于组件与其服务之间关系的性质,它使组件难以进行单元测试:服务实现被硬编码到组件中。如果要在组件上运行单元测试,则需要找到一种方法,将类替换为实际上不与数据库或 Web 服务通信的假类或模拟类。现在想象一下,如果这个问题扩展到数十个或数百个组件。DataAccessService

依赖注入提供了解决此问题的方法。首先,使用抽象来表示服务。最常见的是,这种抽象采用接口的形式。然后,组件代码引用抽象而不是特定的实现:

代码语言:javascript
复制
@code{
    IDataAccessService service;
    List<Contact> contacts;

    protected void OnInitialized()
    {
        contacts = service.GetContacts();
    }
    ...
}

上面的片段有两个问题没有得到解答:

  1. IDataAccessService 是如何变成 DataAccessService 的?
  2. DataAccessService实例化的位置?

要回答第一个问题,我们需要看一下服务注册。

Blazor 服务集合

服务注册涉及到将具体实现映射到抽象。这是通过向 ServiceCollection 添加条目来实现的, ServiceCollectionServiceDescriptor 对象的中央注册表,表示服务类型、其实现和服务的生存期。

注册通常发生在应用程序的 Program 类中的 Main 方法中,其中应用程序的 ServiceCollection 可以通过 WebAssemblyHostBuilderServices 属性访问:

代码语言:javascript
复制
public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebAssemblyHostBuilder.CreateDefault(args);
        builder.RootComponents.Add<App>("app");
        builder.Services.AddSingleton<IDataAccessService, DataAccessService>();
    }
}

在这个实例中, DataAccessService 类被注册为在注入 IDataAccessService 类型时使用的实现。它被注册为单例,这意味着在应用程序的生命周期内只有一个实例可用。

为了回答第二个悬而未决的问题,依赖注入系统负责在引用抽象时提供指定类型的实例,并管理其生存期。

注入

服务是通过注射提供的,注射以不同的方式完成,具体取决于消费者。

代码语言:javascript
复制
@inject命令

Razor 组件

@inject 指令用于使Razor组件可以使用服务。它后面是要注入的类型,以及该类型的实例:

代码语言:javascript
复制
@inject IDataAccessService service
    ...
@code{
 
    List<Contact> contacts;

    protected void OnInitialized()
    {       
        contacts = service.GetContacts();
    }
    ...
}

ComponentBase 类

作为Razor组件的代码隐藏类的类-那些从 ComponentBase 派生或实现 IComponent 的类-不支持构造函数注入。通过将这些类添加为属性并使用 InjectAttribute 装饰它们,可以为这些类提供服务:

代码语言:javascript
复制
public class MyComponent : ComponentBase
{
    [Inject] IDataAccessService service { get; set; }
     
    protected List<Contact> Contacts { get; set; }

    protected override void OnInitialized()
    {       
        contacts = service.GetContacts();
    }
}

其他类

非组件相关类支持标准构造函数注入:

代码语言:javascript
复制
public class MyService
{
    private readonly IDataAccessService _service;

    public MyService(IDataAccessService service) => _service = service;
 
    public void SomeMethod()
    {
        var x = _service.GetContacts();
    }
}

默认服务

默认情况下会注册许多实用程序服务:

Service 服务

Lifetime

Description 描述

HttpClient

Singleton

用于发出HTTP请求并接收其响应。WebAssembly版本使用Fetch API。

NavigationManager

Singleton

包含使用URI和导航状态的帮助程序。

IJSRuntime

Singleton

表示调度JavaScript调用的JavaScript运行时的实例。

生命周期

可以使用以下三种生存期作用域之一注册服务:单一实例、作用域和瞬态。

  • 单一实例Singleton:在应用程序的生命周期中只创建一个服务实例。所有用户在Blazor Server应用程序中共享同一个实例。每个用户都可以在WebAssembly应用程序中有效地获得自己的版本。。
  • 作用域Scoped:在Blazor Server应用程序中,注册为scoped的服务的范围是当前(SignalR)连接(或用户)。作用域服务在WebAssembly应用程序中注册为单例。
  • 瞬态Transient:每次需要时,都会创建一个注册到Transient作用域的服务的新实例。此范围适用于实现 IDisposable 或维护状态的服务。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 科控物联 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 依赖注入 (DI) 是一种通过关注点分离来促进软件松散耦合的技术。在 Blazor 应用程序的上下文中,DI 鼓励你为特定任务开发离散服务,然后将这些服务注入到需要使用其功能的组件和类中。这些依赖类旨在调用针对抽象的操作,而不是针对特定的依赖项实现,从而确保使用类不绑定到特定的实现。这样可以使应用程序更易于维护和测试。
    • Blazor 中的服务
      • Blazor 服务集合
        • 注入
          • Razor 组件
          • ComponentBase 类
          • 其他类
        • 默认服务
        相关产品与服务
        数据保险箱
        数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档