2016-12-03 4 views
4

Wie verwende ich die Schnittstelle IHostingEnvironment, ohne sie in einem Konstruktor zu initiieren?Verwendung von IHostingEnvironment

mein 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(); 
} 

Meine Klasse:

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); 
    } 
} 

Antwort

5

Sie sollten die integrierte Dependency Injection verwenden, wie es Ihren Code entkoppelt und einfacher macht, ohne Sachen zu brechen zu ändern und machen es sehr einfach zu Unit-Test.

Wenn Sie über eine statische Klasse oder Methode darauf zugreifen würden, wird es schwierig, Ihren Code zu testen, da er im Komponententest immer den Projektpfad und nicht eine bestimmte Zeichenfolge zum Testen verwendet.

Die Art, wie Sie es beschrieben haben absolut korrekt und es ist NICHT falsch! Unten nur das vollständige Beispiel.

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); 
    } 
} 

Wenn der env Wert null im Konstruktor ist, müssen Sie es registrieren sich in Startup.cs, wenn ASP.NET-Core es nicht bereits tun:

services.AddSingleton<IHostingEnvironment>(env); 

wo env das ist Instanz an den Startup-Konstruktor übergeben.

+0

Wenn ich 'IHostingEnvironment' im Konstruktor verwende, wie kann ich die Klasse FileReader initiieren? var fileReader = neuer FileReader(); Es erwartet "IHostingEnvironment" als Parameter. – Eyal

+2

Sie instanziieren es nicht, Sie fordern es über Konstruktor an. Wenn Sie DI/IoC verwenden, sollten Sie es ** überall ** verwenden. Wenn Sie es also in der Steuerung brauchen, sieht Ihr Controller-Konstruktor etwas wie 'public MyController (FileReader fileReader)' aus, dann behalten Sie einen Verweis darauf und greifen in der Aktion darauf zu. Wenn du DI benutzt, nennst du niemals 'new' auf deinen Diensten (nur Modelle und bestimmte Framework-Klassen nicht über DI kontrolliert/aufgelöst) – Tseng

+1

Aber du solltest es in eine Schnittstelle aufteilen, die' IFileReader' und 'FileReader' hat und nur die Schnittstelle injiziert . Wenn Sie Unit-Tests schreiben, können Sie die Oberfläche leicht verspotten, was mit 'FileReader' nicht möglich ist. – Tseng

Verwandte Themen