2016-03-31 2 views
1

Ich bin irgendwie neu mit OWIN und IoC und jetzt muss ich einen dynamischen Kontext implementieren, der von Simple Injector basierend auf einem HTTP-Header aufgelöst wird, der identifiziert, wer meine API aufruft. Dieser Ansatz ist vielleicht nicht der beste, also bin ich auch offen für andere mögliche Lösungen.Wie konfiguriert man eine dynamische Verbindungszeichenfolge in einer OWIN-Umgebung basierend auf dem HTTP-Header?

Hier ist meine OWIN Startklasse:

public void Configuration(IAppBuilder app) 
{ 
    var httpConfig = new HttpConfiguration(); 
    var container = new Container(); 
    string connectionString = string.Empty; 

    container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); 

    ConfigureOAuthTokenGeneration(app); 
    ConfigureOAuthTokenConsumption(app); 

    app.Use(async (context, next) => 
    { 
     var customHeader = context.Request.Headers.Get("customHeader"); 
     connectionString = "conStr";//get con based on the header, from a remote DB here 
     await next.Invoke(); 
    }); 

    app.UseOwinContextInjector(container); 

    container.Register<DbContext>(() => new MyDynamicContext(connectionString), 
     Lifestyle.Scoped); 
    //container.Register ...; 

    container.Verify(); 

    httpConfig.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 

    ConfigureWebApi(httpConfig); 
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
    app.UseWebApi(httpConfig); 
} 

Das Problem, das ich mit Blick auf bin, ist, dass die Verbindungszeichenfolge ist immer leer, wenn der DI Rahmen der Instanz erstellt.

Jede Hilfe wird geschätzt.

Antwort

1

In Ihrem Fall sind sowohl die MyDynamicContext als auch die Verbindungszeichenfolge Laufzeitwerte. Wie erläutert here, sollten Laufzeitdaten nicht in Komponenten injiziert werden. Stattdessen sollten Sie eine Abstraktion definieren, mit der Sie den Laufzeitwert abrufen können, nachdem das Objektdiagramm erstellt wurde.

In Ihrem Fall wäre es am besten eine Abstraktion zu haben, die die DbContext, zum Beispiel ermöglicht das Abrufen:

public interface IDbContextProvider { 
    DbContext Context { get; } 
} 

Verbraucher der DbContext Nutzung der IDbContextProvider Abstraktion machen den aktuellen Kontext zu erhalten. Eine Implementierung könnte wie folgt aussehen:

class DbContextProvider : IDbContextProvider { 
    private readonly Func<DbContext> provider; 
    public DbContextProvider(Func<DbContext> provider) { this.provider = provider; } 
    public DbContext Context { get { return this.provider(); } } 
} 

Und die Eintragung dieser DbContextProvider kann aussehen folgt:

var provider = new DbContextProvider(() => GetScopedItem(CreateContext)); 
container.RegisterSingleton<IDbContextProvider>(provider); 

static T GetScopedItem<T>(Func<T> valueFactory) where T : class { 
    T val = (T)HttpContext.Current.Items[typeof(T).Name]; 
    if (val == null) HttpContext.Current.Items[typeof(T).Name] = val = valueFactory(); 
    return val; 
}  

static DbContext CreateContext() { 
    var header = HttpContext.Request.Headers.Get("custHeader"); 
    string connectionString = "conStr";//get con based on the header, from a remote DB here 
    return new MyDynamicContext(connectionString); 
}  
Verwandte Themen