2016-12-03 8 views
4

IHostingEnvironmentインターフェイスをコンストラクタで開始せずに使用するにはどうすればよいですか?IHostingEnvironmentの使い方

私Startup.cs:

public Startup(IHostingEnvironment env) 
{ 
    var builder = new ConfigurationBuilder() 
     .SetBasePath(env.ContentRootPath) 
     .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
     .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
     .AddEnvironmentVariables(); 

    if (env.IsDevelopment()) 
    { 
     // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 
     builder.AddApplicationInsightsSettings(developerMode: true); 
    } 
    Configuration = builder.Build(); 
} 

私のクラス:それはあなたのコードが切り離さになり、より容易なよう

public class FileReader 
{ 
    // I don't want to initiate within a constructor 

    public string ReadFile(string fileName) 
    { 
     // this is wrong! how can I use it? 
     var filename = Path.Combine(IHostingEnvironment.WebRootPath, fileName); 
    } 
} 

答えて

5

あなたはそれを非常にものを壊すことなく変更と作るために統合された依存性注入を使用する必要がありますユニットテストが簡単です。

静的なクラスまたはメソッドを使用してアクセスする場合、コードは単体テストと同じようにテストするのが難しくなります。これは、テストのために特定の文字列ではなくプロジェクトパスを使用します。

あなたがそれを絶対に正しく記述した方法は、NOTが間違っています!以下は完全な例です。

public class FileReader 
{ 
    private readonly IHostingEnvironment env; 
    public FileReader(IHostingEnvironment env) 
    { 
     if(env==null) 
      throw new ArgumentNullException(nameof(env)); 

     this.env = env; 
    } 

    public string ReadFile(string fileName) 
    { 
     var filename = Path.Combine(env.WebRootPath, fileName); 
    } 
} 

env値はコンストラクタでnullある場合は、ASP.NETコアはすでにそれをしない場合は、Startup.csでそれを自分で登録する必要があります。

ENVがある
services.AddSingleton<IHostingEnvironment>(env); 

インスタンスはStartupコンストラクタに渡されます。

+0

コンストラクタで 'IHostingEnvironment'を使用している場合、どのようにしてクラスFileReaderを開始できますか? var fileReader =新しいFileReader();パラメータとして 'IHostingEnvironment'が必要です。 – Eyal

+2

あなたはそれをインスタンス化せず、コンストラクタ経由でリクエストします。 DI/IoCを使用する場合は、**どこでも**使用する必要があります。ですからコントローラのコンストラクタがコントローラ内に必要な場合は、 'public MyController(FileReader fileReader)'のように見えるかもしれません。そして、あなたはそれを参照してアクションにアクセスします。あなたがあなたのサービスで 'new'を呼び出すことは決してありません。(モデルと、DI経由で制御/解決されないフレームワーククラスのみ) – Tseng

+1

しかし、あなたは' IFileReader'と 'FileReader'を持つインターフェースに分割し、 。その後、単体テストを書くときに、簡単にインタフェースをモックできます。これは 'FileReader'では不可能です。 – Tseng