ASP.NET Core中使用GraphQL - 第三章 依赖注入

ASP.NET Core中使用GraphQL


SOLID原则中的D表示依赖倒置原则。这个原则的内容是:

  • 上层模块不应该直接依赖底层模块,而应该依赖其抽象
  • 抽象不应该依赖于细节, 细节应该依赖抽象

来源:WIKIPEDIA

在一个模块中创建一个其他模块的实例会导致这个模块与其他模块之间的紧耦合。 为了让不同的模块解耦,我们需要遵循依赖倒置原则。按照这种原则,一个模块不会依赖于其他模块的实现,会依赖于其他模块的抽象,例如接口。

一个抽象会存在许多个实现。无论何时我们碰到一个抽象,我们都需要传递一个该抽象的实现。所以我们需要一个类来负责配置他们之间的映射,这里我们称这个类为依赖注入容器(dependency injection container)。

ASP.NET Core中已经内置了一个依赖注入容器。它使用起来非常简单。它不仅能够配置抽象接口与实现类之间的映射,还可以配置实现类实例的生命周期。

在我们之前的Hello World项目中,我们没有关注过实例的生命周期。到目前为止,我们会将所有实现类对象设置为了Singleton

这里我们首先需要解除对DocumentWriterDocumentExecuter类依赖。方法就是使用抽象接口IDocumentWriterIDocumentExecuter替换DocumentWriterDocumentExecuter

Copy

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDocumentWriter, DocumentWriter>();
    services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
}

对于HelloWorldQuery实例,我们没有编写任何抽象接口,所以这里我们简单的使用了其原始实现。

Copy

services.AddSingleton<HelloWorldQuery>(); 

当前的结构(Schema)中包含了一个query, 在后续的博文中我们还会添加mutation和其他字段,所以这里我们最好创建一个独立的类来设置它。所以这里我们创建了一个HelloWorldSchema类,它继承自Schema, 并在构造中注入了一个HelloWorldQuery实例。

Copy

public class HelloWorldSchema : Schema
{
    public HelloWorldSchema(HelloWorldQuery query)
    {
        Query = query;
    }
}

最后我们在Startup.cs文件的Configure方法中注入HelloWorldSchame

Copy

services.AddSingleton<ISchema, HelloWorldSchema>();  

TIPS:ISchemagraphql-dotnet库中一个接口,Schema类实现了ISchema接口

现在我们将之前创建的中间件移到一个单独的类中,我们将它命名为GraphQLMiddleware, 其代码如下。

Copy

public class GraphQLMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IDocumentWriter _writer;
    private readonly IDocumentExecuter _executor;
    private readonly ISchema _schema;

    public GraphQLMiddleware(RequestDelegate next,
                             IDocumentWriter writer,
                             IDocumentExecuter executor,
                             ISchema schema)
    {
        _next = next;
        _writer = writer;
        _executor = executor;
        _schema = schema;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        if (httpContext.Request.Path.StartsWithSegments("/api/graphql")
            && string.Equals(httpContext.Request.Method,
                             "POST",
                             StringComparison.OrdinalIgnoreCase))
        {
            string body;
            using (var streamReader = new StreamReader(httpContext.Request.Body))
            {
                body = await streamReader.ReadToEndAsync();

                var request = JsonConvert.DeserializeObject<GraphQLRequest>(body);

                var result = await _executor.ExecuteAsync(doc =>
                {
                    doc.Schema = _schema;
                    doc.Query = request.Query;
                }).ConfigureAwait(false);

                var json = await _writer.WriteToStringAsync(result);
                await httpContext.Response.WriteAsync(json);
            }
        }
        else
        {
            await _next(httpContext);
        }
    }
}

这里你会注意到我们是如何使用抽象接口来解耦的,在GraphQLMiddleware的构造函数中,我们注入了当前中间件所需的所有服务IDocumentWriterIDocumentExecuter, 以及ISchema

最后我们需要将这个中间件注册到应用程序管道中。IApplicationBuilder接口提供了一个扩展方法UseMiddleware, 我们可以使用它来注册中间件。所以最终Configure方法中的代码如下:

Copy

public void Configure(IApplicationBuilder app,
    IHostingEnvironment env)
{
    app.UseMiddleware<GraphQLMiddleware>();
}

现在我们重新使用POSTMAN来测试。

结果正确输出了。

本文源代码:https://github.com/lamondlu/GraphQL_Blogs/tree/master/Part%20III

原文地址:https://www.cnblogs.com/lhxsoft/p/11903536.html

时间: 2024-12-13 23:26:59

ASP.NET Core中使用GraphQL - 第三章 依赖注入的相关文章

ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储

ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量 本篇中我将演示如何配置持久化仓储,这里原文中是使用的Postgres, 这里我改用

ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量

ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL 字段# 我们已经很好的理解了GraphQL中的字段.在之前HelloWorldQuery的例子中,我们添加了2个字段hello和howdy. 它们都是标量字段.正

ASP.NET Core 中文文档 第三章 原理(1)应用程序启动

原文:Application Startup 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程序提供了处理每个请求的完整控制.Startup 类是应用程序的入口(entry point),这个类可以设置配置(configuration)并且将应用程序将要使用的服务连接起来.开发人员可以在 Startup 类中配置请求管道,该管道将用于处理应用程序的所有请求. 章节: Startup 类 Co

ASP.NET Core 中文文档 第三章 原理(7)配置

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 原文:Configuration 作者:Steve Smith.Daniel Roth 翻译:刘怡(AlexLEWIS) 校对:孟帅洋(书缘) ASP.NET Core 支持多种配置选项.应用程序配置数据内建支持读取 JSON.XML 和 IN

ASP.NET Core 中文文档 第三章 原理(2)中间件

原文:Middleware 作者:Steve Smith.Rick Anderson 翻译:刘怡(AlexLEWIS) 校对:许登洋(Seay) 章节: 什么是中间件 用 IApplicationBuilder 创建中间件管道 内置中间件 编写中间件 扩展资源 查看或下载样例代码 什么是中间件 中间件是用于组成应用程序管道来处理请求和响应的组件.管道内的每一个组件都可以选择是否将请求交给下一个组件.并在管道中调用下一个组件之前和之后执行某些操作.请求委托被用来建立请求管道,请求委托处理每一个 H

ASP.NET Core 中文文档 第三章 原理(14)服务器

原文:Servers 作者:Steve Smith 翻译:谢炀(Kiler) 校对:许登洋(Seay).姚阿勇(Dr.Yao) ASP.NET Core 已完全从承载应用程序的 Web 服务器环境中分离.ASP.NET Core 可以承载于 IIS 和 IIS Express ,以及使用 Kestrel 和 WebListener HTTP Server 的自承载环境中.此外,开发人员和第三方软件供应商可以创建自定义的服务器来承载 ASP.NET Core 应用程序. 查看和下载示例代码 服务器

ASP.NET Core 中文文档 第三章 原理(5)错误处理

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 原文:Error Handling 作者:Steve Smith 翻译:谢炀(Kiler) 校对:高嵩(jack2gs).何镇汐 当你的ASP.NET应用发生错误的时候, 你可以采用本文所述的各种方法来处理这些问题. 章节: 配置错误处理页面

ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系

ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量 ASP.NET Core中使用GraphQL - 第六章 使用EF Co

使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(六)-- 依赖注入

本篇将介绍Asp.Net Core中一个非常重要的特性:依赖注入,并展示其简单用法. 第一部分.概念介绍 Dependency Injection:又称依赖注入,简称DI.在以前的开发方式中,层与层之间.类与类之间都是通过new一个对方的实例进行相互调用,这样在开发过程中有一个好处,可以清晰的知道在使用哪个具体的实现.随着软件体积越来越庞大,逻辑越来越复杂,当需要更换实现方式,或者依赖第三方系统的某些接口时,这种相互之间持有具体实现的方式不再合适.为了应对这种情况,就要采用契约式编程:相互之间依