2016-05-13 5 views
0

私はいくつかのコントローラを備えたASP.NET Web Api 2 RESTサービスを持っています。これらのコントローラのそれぞれのコンストラクタには、StructureMapで注入する必要があるILogger引数があります。 IPアドレスなどのクライアント固有の情報を取得し、ログファイルを特定のパスに保存するために、リクエストごとにILoggerをインスタンス化することは可能ですか?WebリクエストごとのStructureMap注入

これはDefaultRegistryで実行しようとしているコードですが、HttpContextは常にnullです。どこが間違っていますか?

For<ILogger>() 
    .Use(() => new TextFileLogger(
     HttpContext.Current.Request.UserHostAddress + 
     DirectorySeparatorChar + "log.txt")); 

答えて

4

私はStructureMapの専門家ではありませんが、私はこの問題を理解しています。問題は、実行時データを使用してオブジェクトグラフを構築することです。そしてinjecting runtime data is an anti-pattern

ここでの簡単な解決策は、コンポジションルートに直接HttpContextを使用するのではなく、FileLoggerのパスを決定するために使用できるプロバイダを作成することです。この場合、この新しいプロバイダーとしてのFileLoggerはシングルトンになる可能性があります。

プロバイダーは(#6構文c)のような単純なものでした:

public class HttpLogfileProvider : ILogFileProvider 
{ 
    public string PathToLogfile => 
     Path.Combine(HttpContext.Current.Request.UserHostAddress, "log.txt"); 
} 

はあなたの次のようFileLoggerは、このプロバイダを使用することができます。

public class FileLogger : ILogger 
{ 
    private readonly ILogFileProvider logFileProvider; 
    public FileLogger(ILogFileProvider logFileProvider) 
    { 
     this.logFileProvider = logFileProvider; 
    } 

    public void Log(string message) 
    { 
     using (var writer = new StreamWriter(this.currentLogFile)) 
     { 
       writer.WriteLine(message); 
     } 
    } 

    private string currentLogFile => 
     this.logFileProvider.PathToLogFile; 
} 

を私はのStructureMapユーザーではないんだけど登録は次のようにする必要があります:

For<ILogFileProvider>.Use<HttpLogfileProvider>.Singleton; 
For<ILogger>.Use<FileLogger>.Singleton; 
+0

本当にありがとうございます。私は依存症注入の新人です。これらの情報は私にとって純粋な金です! –

関連する問題