ASP.NET Core中使用GraphQL


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

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

来源:WIKIPEDIA

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

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

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

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

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

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

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

services.AddSingleton<HelloWorldQuery>();

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

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

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

services.AddSingleton<ISchema, HelloWorldSchema>();

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

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

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的构造函数中,我们注入了当前中间件所需的所有服务IDocumentWriter, IDocumentExecuter, 以及ISchema

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

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

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

结果正确输出了。

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

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

  1. ASP.NET Core中使用GraphQL - 第四章 GraphiQL

    ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...

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

    ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...

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

    ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP ...

  4. ASP.NET Core中使用GraphQL - 第七章 Mutation

    ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间 ...

  5. ASP.NET Core 中文文档 第三章 原理(10)依赖注入

    原文:Dependency Injection 作者:Steve Smith 翻译:刘浩杨 校对:许登洋(Seay).高嵩 ASP.NET Core 的底层设计支持和使用依赖注入.ASP.NET Co ...

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

    原文:Application Startup 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:谢炀(kiler398).许登洋(Seay) ASP.NET Core 为你的应用程 ...

  7. ASP.NET Core 中文文档 第三章 原理(6)全球化与本地化

    原文:Globalization and localization 作者:Rick Anderson.Damien Bowden.Bart Calixto.Nadeem Afana 翻译:谢炀(Kil ...

  8. ASP.NET Core 中文文档 第三章 原理(13)管理应用程序状态

    原文:Managing Application State 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩 在 ASP.NET Core 中,有多种途径可以对应用程序的状态进行 ...

  9. ASP.NET Core 中文文档 第三章 原理(11)在多个环境中工作

    原文: Working with Multiple Environments 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core 介绍了支持在多个环境中管 ...

随机推荐

  1. 关于Kafka配额的讨论(1)

    Kafka自0.9.0.0版本引入了配额管理(quota management),旨在broker端对clients发送请求进行限流(throttling).目前Kafka支持两大类配额管理: 网络带 ...

  2. PLINQ的 ForAll 对比集合的ForEach

    在 PLINQ 中,还可以使用 foreach 执行查询以及循环访问结果. 但是,foreach 本身不会并行运行,因此,它要求将所有并行任务的输出合并回该循环正在上面运行的线程中. 在 PLINQ ...

  3. Protostuff序列化分析

    前言最近项目中需要将业务对象直接序列化,然后存数据库:考虑到序列化.反序列化的时间以及生产文件的大小觉得Protobuf是一个很好的选择,但是Protobuf有的问题就是需要有一个.proto的描述文 ...

  4. bzoj5248 [2018多省省队联测]一双木棋

    直接hash+爆搜即可. #include <cstdio> #include <cstring> #include <iostream> #include < ...

  5. 【Homework】LCA&RMQ

    我校是神校,作业竟然选自POJ,难道不知道“珍爱生命 勿刷POJ”么? 所有注明模板题的我都十分傲娇地没有打,于是只打了6道题(其实模板题以前应该打过一部分但懒得找)(不过感觉我模板还是不够溜要找个时 ...

  6. BZOJ_2068_[Poi2004]SZP_树形DP

    BZOJ_2068_[Poi2004]SZP_树形DP Description Byteotian 中央情报局 (BIA) 雇佣了许多特工. 他们每个人的工作就是监视另一名特工. Byteasar 国 ...

  7. BZOJ_1861_[Zjoi2006]Book 书架_splay

    BZOJ_1861_[Zjoi2006]Book 书架_splay 题意: 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在 ...

  8. sum() 函数性能堪忧,列表降维有何良方?

    本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/mK1nav2vKykZaKw_TY-rtw Python 的内置函数 ...

  9. go语言调度器源代码情景分析之二:CPU寄存器

    本文是<go调度器源代码情景分析>系列 第一章 预备知识的第1小节. 寄存器是CPU内部的存储单元,用于存放从内存读取而来的数据(包括指令)和CPU运算的中间结果,之所以要使用寄存器来临时 ...

  10. 分布式日志框架Exceptionless之生产环境部署步骤

    Exceptionless 是一个开源的实时的日志收集框架,它将日志收集变得简单易用并且不需要了解太多的相关技术细节及配置.本篇基于我的上一篇<基于Exceptionless实现分布式日志> ...