2016-08-17 5 views
2

アプリケーションでasp.netコアのようなミドルウェアアーキテクチャを使用するにはどうすればいいですか?アプリケーション用にASP.NET Coreのアーキテクチャのようなミドルウェアを使用するにはどうすればよいですか?

この目標にはどのパターンが必要ですか?

新しい機能を追加するためのこのような設計の参考資料はありますか?

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
    loggerFactory.AddDebug(); 

    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseDatabaseErrorPage(); 
     app.UseBrowserLink(); 
    } 
    else 
    { 
     app.UseExceptionHandler("/Home/Error"); 
    } 

    app.UseStaticFiles(); 

    app.UseIdentity(); 

    // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715 

    app.UseMvc(routes => 
    { 
     routes.MapRoute(
      name: "default", 
      template: "{controller=Home}/{action=Index}/{id?}"); 
    }); 
} 

非常に単純な設定方法では、アプリケーションに新しい機能を追加することができます。

+0

あなたは具体的に何を追加していますか、それを一般的に行う方法を知りたいですか? – Nico

+0

@Nico私はこれについて何の考えも持っていませんが、パターンや他のパターンの組み合わせを最初に知りません。そのサンプルや簡単なサンプルに関する情報があります。 – JKL

答えて

5

私はどうしたらまず最初は、これは、ミドルウェアを使用する方法を理解するのに役立ちますとpraciticesは、独自のカスタムミドルウェアを実装するために従うことMiddleware - Asp.Net Documentation

を読まされます。ドキュメント

ミドルウェアから直接採取

が要求および応答を処理するため アプリケーションパイプラインに組み込まれているソフトウェアコンポーネントです。各コンポーネント は、 パイプライン内の次のコンポーネントに要求を渡すかどうかを選択し、次の コンポーネントがパイプラインで呼び出される前後に特定のアクションを実行できます。要求デリゲートは、 要求パイプラインの構築に使用されます。要求デリゲートは各HTTP 要求を処理します。

このように、コンポーネントは要求と応答を処理できます。ミドルウェアは、アプリケーションミドルウェアコレクションに追加された順に実行されます。

app.UseStaticFiles();は、静的ファイル(画像、CSS、スクリプトなど)を処理するためのmiddlwareを追加します。

パイプラインで独自の処理を追加したい場合、ミドルウェアクラスを下のサンプルとして作成できます。

public class GenericMiddleware 
{ 
    public GenericMiddleware(RequestDelegate next) 
    { 
     _next = next; 
    } 

    readonly RequestDelegate _next; 

    public async Task Invoke(HttpContext context, IHostingEnvironment hostingEnviroment) 
    { 
     //do something 

     await _next.Invoke(context); 
    } 
} 

ここで興味深い点がいくつかあります。最初にコンストラクタをオフにすると、呼び出される次のミドルウェアオブジェクトは本質的に(しかし正確には)そのものではなく、RequestDelegateになります。

次に、独自のInvokeメソッドを実装します。このメソッドはパラメータとしてHttpContextを取る必要があり、また、IoCコンテナから追加の依存関係を注入することもできます(私の例ではIHostingEnvironmentインスタンス)。

このメソッドは、実行する必要があるコードを実行し、RequestDelegateを実行して次のミドルウェアクラスを呼び出すawait _next.Invoke(context);を呼び出します。

は今、あなたは、単にstartup.csファイルでのごConfigure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)方法で

app.UseMiddleware<GenericMiddleware>();を呼び出すことができるアプリケーションミドルウェアにこれを追加します。

または、次のような単純な拡張メソッドを作成します。

その後、app.UseGenericMiddleware();

今どのように、なぜあなたがあなた自身のミドルウェアを実装するのはあなた次第ですと呼ばれる

public static class GenericMiddlewareExtensions 
{ 
    public static IApplicationBuilder UseGenericMiddleware(this IApplicationBuilder app) 
    { 
     app.UseMiddleware<GenericMiddleware>(); 
     return app; 
    } 
} 

。しかし、それがない場合は、次のRequestDelegateを呼び出すことはミドルウェアに任されています。

これは、データベースがインストールされているかどうかを確認するプロジェクトの1つの例です。そうでなければ、要求をインストールページにリダイレクトします。 !DatabaseHelper.IsDatabaseInstalled()は、我々は、応答をリダイレクトしますが_nextRequestDelegateを呼び出すいけない場合、あなたが見ることができるように

public class InstallationMiddleware 
{ 
    private readonly RequestDelegate _next; 
    private readonly ILogger _logger; 

    public InstallationMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) 
    { 
     _next = next; 
     _logger = loggerFactory.CreateLogger<InstallationMiddleware>(); 
    } 

    public async Task Invoke(HttpContext context) 
    { 
     _logger.LogInformation("Handling request: " + context.Request.Path); 
     if (context != null && !DatabaseHelper.IsDatabaseInstalled()) 
     { 
      if (!context.Request.Path.ToString().ToLowerInvariant().StartsWith("/installation")) 
      { 
       context.Response.Redirect("/installation"); 
       return; 
      } 
     } 

     await _next.Invoke(context); 
     _logger.LogInformation("Finished handling request."); 
    } 
} 

ここでもまた、ドキュメントはそれ自体について語ります。

+0

ありがとうございます。サンプルとしてこのアーキテクチャ?例えば、ビルダーパターンと言うと、これは実装に関して多くのサンプルを持っているので、私は一般的な目的でHttpだけではないサンプルが必要ですか?このパターンはMEFの代替品ですか?なぜMicrosoftがmefを使っていないのですか(機能の追加など)? – JKL

+0

@JKLミドルウェア(asp.netコア用)は、HTTPコンテキストのみに直接関係しています。たぶん私はあなたが探しているものに正確に従っていないでしょう。 – Nico

+0

.NET Coreで必要なときにアプリケーションに機能を追加するための提案はありますか?誰かがアプリケーションのために自分自身の機能を追加する必要があるとき? .NET FrameworkではMEF + Appdomainを使用しましたが、どちらも.NETコアには存在しません。 – JKL

1

私が取り組んでいるプロジェクトの簡単なプロトタイプ実装は、ASP.NET Coreとは関係がないため、アーキテクチャやその実装を理解していない人は、概念を把握しやすくなる可能性があります。

ここで遊んでいるデザインパターンは、責任パターンチェーンと呼ばれます。

だから我々は、必要がある最初の事は、アプリケーションのためのデリゲートを定義することです:

public delegate void InputDelegate(char key); 

その後、我々はので、ここでそれを消費するために何かを必要とする非常に単純なイベント/メインループの実装です:

internal class TerminalHost 
{ 
    private InputDelegate _inputDelegate; 

    public TerminalHost() 
    { 
     // Initializes the first delegate to be invoked in the chain. 
     _inputDelegate = Console.Write; 
    } 

    internal void Start() 
    { 
     CancellationTokenSource tokenSource = new CancellationTokenSource(); 

     while (!tokenSource.IsCancellationRequested) { 
      ConsoleKeyInfo keyInfo = Console.ReadKey(); 

      _inputDelegate(keyInfo.KeyChar); 
     } 
    } 

    /// <summary> 
    /// Adds the middleware to the invocation chain. 
    /// </summary> 
    /// <param name="middleware"> The middleware to be invoked. </param> 
    /// <remarks> 
    /// The middleware function takes an instance of delegate that was previously invoked as an input and returns the currently invoked delegate instance as an output. 
    /// </remarks> 
    internal void Use(Func<InputDelegate, InputDelegate> middleware) 
    { 
     // Keeps a reference to the currently invoked delegate instance. 
     _inputDelegate = middleware(_inputDelegate); 
    } 
} 

最後に、TerminalHostクラスのインスタンスを作成し、メソッドを呼び出すと、これは次のようになります。

class Program 
{ 
    static void Main(string[] args) 
    { 
     TerminalHost terminal = new TerminalHost(); 

     terminal.Use(next => ch => { 
      Console.WriteLine(ch); 

      next(ch); 
     }); 

     terminal.Start(); 
    } 
} 

私はそれが理にかなっており、そこに誰かに役立つことを望みます。 :)

関連する問題