2016-06-06 4 views
0

Innerhalb Ich bin eine Reihe von Diensten einrichten (das funktioniert). In der gleichen Methode versuche ich einen benutzerdefinierten Dateianbieter (für Razor) zu konfigurieren. Es sieht wie folgt aus:Request Instanz innerhalb von ConfigureServices

services.AddMvc() 
     .AddRazorOptions(options => 
     { 
      options.FileProvider = new CustomFileProvider(???); 
     }); 

CustomFileProvider einige Abhängigkeiten hat (dass alle konfiguriert sind), aber wie kann ich bitte die DI mir zu geben, eine Instanz von CustomFileProvider Recht, nachdem alle Dienste konfiguriert wurden?

Von dem, was ich sehen kann, injiziert die DI nur in Konstruktoren, aber in meinem Fall brauche ich eine "Bitte geben Sie mir eine Instanz von CustomFileProvider hier" -Option.

+0

Sie können nicht in ConfigureServices auflösen, da der Container nach dem Aufruf von 'ConfigureServices' und vor dem Aufruf von' Configure' erstellt wird. Wenn Sie keine sehr komplexe Abhängigkeitsstruktur für den Dateianbieter haben, sollten Sie sie manuell einspeisen. – Tseng

Antwort

2

Wenn Sie beim Konfigurieren einiger Optionen Dienste aus dem Container auflösen möchten, müssen Sie die IConfigureOptions<TOption>-Infrastruktur nutzen, die von MVC zum Einrichten der Standardwerte der Option verwendet wird. Ein Beispiel finden Sie in RazorViewEngineOptionsSetup.

Zuerst fügen Sie die Dienste, die Sie in die Sammlung benötigen:

services.AddSingleton<IDependency1, Dependency1>(); 
services.AddSingleton<IDependency2, Dependency2>(); 

Dann die Setup-Klasse implementieren:

public class CustomFileProviderRazorViewEngineOptionsSetup : ConfigureOptions<RazorViewEngineOptions> 
{ 
    public CustomFileProviderRazorViewEngineOptionsSetup(IServiceProvider serviceProvider) 
     : base(options => ConfigureRazor(options, serviceProvider)) 
    { 
    } 

    private static void ConfigureRazor(RazorViewEngineOptions options, IServiceProvider serviceProvider) 
    { 
     // Alternative 1 - Resolve each service and new up the instance. 
     var dependency1 = serviceProvider.GetService<IDependency1>(); 
     var dependency2 = serviceProvider.GetService<IDependency2>(); 

     options.FileProviders.Add(new CustomFileProvider(dependency1, dependency2)); 

     // Alternative 2 - Same as alternative 1, but with moar magic ;) 
     options.FileProviders.Add(ActivatorUtilities.CreateInstance<CustomFileProvider>(serviceProvider)); 

     // Alternative 3 - Just resolve CustomFileProvider from the service provider. 
     // This requires it to be registered first, of course. 
     options.FileProviders.Add(serviceProvider.GetService<CustomFileProvider>()); 
    } 
} 

Das aus dem Behälter gelöst wird, so dass es Ihnen erlauben, werde injizieren Sie eine IServiceProvider, die wieder verwendet werden kann, um die Dienste zu lösen, die Sie benötigen. Sie könnten optional die CustomFileProvider in den Behälter hinzufügen und lösen direkt stattdessen wie in alternative 3.

Schließlich fügen Sie die Setup-Klasse in den Dienst Kollektion:

services.TryAddEnumerable(
    ServiceDescriptor.Transient< 
     IConfigureOptions<RazorViewEngineOptions>, 
     CustomFileProviderRazorViewEngineOptionsSetup>()); 

Dies wird das Setup zu den Optionen hinzufügen Builder-Pipeline, was bedeutet, dass sie mit den anderen registrierten Instanzen von IConfigureOptions<RazorViewEngineOptions> ausgeführt wird, um das Optionsobjekt einzurichten.

+0

+1. Sie könnten sogar 'options.FileProviders.Add (ActivatorUtilities.CreateInstance (serviceProvider, typeof (CustomFileProvider)))} verwenden, um die Instanziierung etwas zu vereinfachen. – Pinpoint

+0

Ja. Ein paar Alternativen hinzugefügt :) – khellang

Verwandte Themen