2017-07-18 75 views
0

我有一個多租戶MVC5 webapp,它使用Autofac v3.5.2和Autofac.Mvc5 v3.3.4。解決OWIN啓動類中的Autofac依賴關係

我的Autofac DI接線發生在我的MVC項目中的一個類中。對於身份驗證,我們使用OWIN OpenId middleware與Azure B2C進行集成。在OWIN啓動類中,我需要依賴項來使用來自當前請求的信息來設置tenantId/clientId。 我嘗試通過抓住依賴性:

DependencyResolver.Current.GetService<...>(); 

然而,這總是拋出ObjectDisposedException

實例不能得到解決,嵌套的壽命可以,因爲它已經被設置爲不從這個LifetimeScope創建。

我們在我們的應用程序中有一個ISiteContext,它有一個請求生命週期。它將獲得特定於當前請求的配置值。我試圖取這些值,如下所示:

private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy) 
{ 
    var options = new OpenIdConnectAuthenticationOptions 
     { 
      Notifications = new OpenIdConnectAuthenticationNotifications 
      { 
       ... 
       RedirectToIdentityProvider = SetSettingsForRequest 
      } 
     } 
} 

private Task SetSettingsForRequest(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) 
{ 
    var siteContext = DependencyResolver.Current.GetService<ISiteContext>(); 
    context.ProtocolMessage.ClientId = siteContext.ClientId; 
    return Task.FromResult(0); 
} 

嘗試在SetSettingsForRequest中使用DependencyResolver時發生此錯誤。我不知道我在這裏做錯了什麼。目前我沒有Autofac我的啓動Configuration(IAppBuilder app)方法中的DI設置,因爲這已經在我的MVC項目中設置。

+0

你能分享更多的代碼嗎?你是如何獲得'tenantId'的? –

+0

@CyrilDurand我添加了一個代碼示例,顯示我試圖解析依賴關係以獲取每個請求的客戶端的位置 –

回答

0

恐怕現在你需要在OWIN管道中設置DI。這不是一個困難的操作。

你必須:

這樣做意味着Autofac將在OWIN級別創建堆棧中每個請求的生命期範圍,這將允許您從OWIN上下文獲取HTTP請求生命週期範圍:

private Task SetSettingsForRequest(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context) 
{ 
    // getting the OWIN context from the OIDC notification context 
    var owinContext = context.OwinContext; 

    // that's an extension method provided by the Autofac OWIN integration 
    // see https://github.com/autofac/Autofac.Owin/blob/1e6eab35b59bc3838bbd2f6c7653d41647649b01/src/Autofac.Integration.Owin/OwinContextExtensions.cs#L19 
    var lifetimeScope = owinContext.GetAutofacLifetimeScope(); 

    var siteContext = lifetimeScope.GetService<ISiteContext>(); 
    context.ProtocolMessage.ClientId = siteContext.ClientId; 
    return Task.FromResult(0); 
} 

我希望這可以幫助你克服這個問題。

+0

將嘗試您的建議並在此處記錄結果。謝謝! –

0

作爲的MickaëlDerriey指出,下面的代碼是能夠在OWIN解決請求範圍的依賴性的溶液:

public class Startup 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var builder = new ContainerBuilder(); 
     // Register dependencies, then... 
     var container = builder.Build(); 

     // Register the Autofac middleware FIRST. This also adds 
     // Autofac-injected middleware registered with the container. 
     app.UseAutofacMiddleware(container); 

     // ...then register your other middleware not registered 
     // with Autofac. 
    } 
} 

,然後在以後的任何代碼中使用來解決依賴性:

// getting the OWIN context from the OWIN context parameter 
var owinContext = context.OwinContext; 
var lifetimeScope = owinContext.GetAutofacLifetimeScope(); 
var siteContext = lifetimeScope.GetService<ISiteContext>(); 
context.ProtocolMessage.ClientId = siteContext.ClientId; 

使用此解決方案,我沒有任何問題解決請求範圍的依賴關係,因爲Autofac似乎符合OWIN創建/處理請求範圍的方式。