ASP.NET Core中使用GraphQLhtml
SOLID
原則中的D
表示依賴倒置原則。這個原則的內容是:git
- 上層模塊不該該直接依賴底層模塊,而應該依賴其抽象
- 抽象不該該依賴於細節, 細節應該依賴抽象
來源:WIKIPEDIAgithub
在一個模塊中建立一個其餘模塊的實例會致使這個模塊與其餘模塊之間的緊耦合。 爲了讓不一樣的模塊解耦,咱們須要遵循依賴倒置原則。按照這種原則,一個模塊不會依賴於其餘模塊的實現,會依賴於其餘模塊的抽象,例如接口。json
一個抽象會存在許多個實現。不管什麼時候咱們碰到一個抽象,咱們都須要傳遞一個該抽象的實現。因此咱們須要一個類來負責配置他們之間的映射,這裏咱們稱這個類爲依賴注入容器(dependency injection container)。c#
ASP.NET Core中已經內置了一個依賴注入容器。它使用起來很是簡單。它不只可以配置抽象接口與實現類之間的映射,還能夠配置實現類實例的生命週期。api
在咱們以前的Hello World項目中,咱們沒有關注過實例的生命週期。到目前爲止,咱們會將全部實現類對象設置爲了Singleton
。app
這裏咱們首先須要解除對DocumentWriter
和DocumentExecuter
類依賴。方法就是使用抽象接口IDocumentWriter
和IDocumentExecuter
替換DocumentWriter
和DocumentExecuter
。async
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:
ISchema
是graphql-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