2017-02-06 14 views
5

startup.csのマッピングサービスを使用して.NETコア依存関係注入を使用するコードをリファクタリングしようとしています。 IRequestDatabaseLoggerを新しく作成するのではなく、ここに挿入したいと思います。ただし、コンストラクタ内にコンテキストが必要です。どうすればこれを達成できますか?それはDIフレームワークなしでも可能ですか?それはコンストラクタでコンテキストを必要とするしかしコンストラクタの依存関係を持つロガーの挿入

public class ActionFilter : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext context) 
     { 
      var requestDatabaseLogger = new RequestDatabaseLogger(context); 
      long logId = requestDatabaseLogger.Log(); 

      context.HttpContext.AddCurrentLogId(logId); 

      base.OnActionExecuting(context); 
     } 
    } 
+2

属性に役立つ何もしないようにします。属性は[ここ](http://blog.ploeh.dk/2014/06/13/passive-attributes/)および[ここ](https://www.cuttingedge.it/blogs/steven)で説明されているように受動的でなければなりません。 /pivot/entry.php?id=98)。 – Steven

+0

関連:https://stackoverflow.com/a/29916075/264697 – Steven

+1

私はあなたの意味だと思う*避けてください*説明したように、ここに示したように、私は工場の抽象化の使用に対して助言... – ssmith

答えて

8

hereに記載されているように、アプリケーションコンポーネントの構成を実行時データに依存させるのがアンチパターンです。この記事では、これらの問題を一般的に解決する方法について説明します。

これは、おそらく、コンポーネントがASP.NET CoreのIHttpContextAccessor抽象化に依存する必要があることを意味します。これは、参照されている記事で説明されているパターンです。

また、この記事で説明したように、Logメソッドを使用して、必要なランタイムデータをロガーに渡すことができます。

0

コンストラクタにRequestDatabaseLoggerFactoryを挿入します。これを使用してRequestDatabaseLoggerインスタンスを作成できます。これを達成するためのtypeFilterを使用し、フィルタの内部(ロガーまたはコンテキストにこの場合)依存性を有するフィルタをラップする必要があり

+1

(有益な何かをやって)防ぐことはできません[ここ](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=100)。 – Steven

2

public interface IRequestDatabaseLoggerFactory { 
    IRequestDatabaseLogger Create(ActionExecutingContext context); 
} 
public class RequestDatabaseLoggerFactory : IRequestDatabaseLoggerFactory { 
    public IRequestDatabaseLogger Create(ActionExecutingContext context) { 
     return new RequestDatabaseLogger(context); 
    } 
} 

public class ActionFilter : ActionFilterAttribute 
{ 
    public ActionFilter(IRequestDatabaseLoggerFactory factory) { 
     _factory = factory; 
    } 

    private readonly IRequestDatabaseLoggerFactory _factory; 

    public override void OnActionExecuting(ActionExecutingContext context) 
    { 
     var requestDatabaseLogger = _factory.Create(context); 
     long logId = requestDatabaseLogger.Log(); 

     context.HttpContext.AddCurrentLogId(logId); 

     base.OnActionExecuting(context); 
    } 

}。私はこれの詳細な例を私のMSDN Article on ASP.NET Core Filtersに示します。関連するソースコードはhereです(ValidateAuthorExistsフィルタを見てください)。

はここで、それはあなたのシナリオでどのように見えるかです:

public class MyFilterAttribute : TypeFilterAttribute 
{ 
    public MyFilterAttribute():base(typeof(MyFilterImpl)) 
    { 
    } 

    private class MyFilterImpl : IAsyncActionFilter 
    { 
     public MyFilterImpl(*inject dependencies here*) 
     {} 
    } 
} 

これは、あなたはまだ基本的なアクションフィルタへの依存性を注入しながら、.NETのコアの属性を使用する方法です。私はDevIQ.comの今後のASP.NET Core Quickstartコースでもこれをカバーします(今月の終わりを見てください)。

関連する問題