2016-03-31 33 views
1

OWIN ve IoC'yi kullanıyorum ve şimdi API'mi kimin aradığını belirleyen bir HTTP üstbilgisine dayanan Simple Injector tarafından çözülen dinamik bir bağlamı uygulamam gerekiyor. Bu yaklaşım en iyisi olmayabilir, bu yüzden başka olası çözümlere de açığım.HTTP üstbilgisine bağlı olarak bir OWIN ortamında dinamik bağlantı dizesi nasıl yapılandırılır?

İşte benim Owin başlangıç ​​sınıfı var:

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

karşılaştığım sorun DI çerçeve örneğini oluşturur bağlantı dizesi her zaman boş olmasıdır.

Herhangi bir yardım için teşekkür ederiz.

cevap

1

Sizin durumunuzda, hem MyDynamicContext hem de bağlantı dizesi çalışma zamanı değerleridir. here açıklandığı gibi, çalışma zamanı bileşenleri bileşenlere enjekte edilmemelidir. Bunun yerine, nesne grafiği oluşturulduktan sonra çalışma zamanı değerini almayı sağlayan bir soyutlama tanımlamanız gerekir. Senin durumunda

, bu örneğin DbContext almaya olanak veren bir soyutlama olması iyi olurdu: DbContext ait

public interface IDbContextProvider { 
    DbContext Context { get; } 
} 

Tüketiciler güncel içeriği almak için IDbContextProvider soyutlama yararlanabilir. olarak görünebilir bir uygulama aşağıdaki gibidir:

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

Ve bakabilirsiniz bu DbContextProvider kayıt aşağıdaki gibidir:

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