2015-01-21 48 views
0

我有一個現有的使用Autofac的MVC 4應用程序,並且我有其他具有autofac模塊的程序集。如果沒有SignalR/autofac集成,我的應用程序就IOC而言完美無缺。我在SignalR集線器中添加了我試圖通過構造函數注入依賴關係的信息。我遵循文檔並實施了代碼示例。Autofac - 帶OWIN的SignalR。獲得對ContainerBuilder的參考

http://autofac.readthedocs.org/en/latest/integration/signalr.html

導致這下面的類:

public class SignalRConfig 
{ 
    public void Configuration(IAppBuilder app) 
    { 
     var builder = new ContainerBuilder(); 
     var config = new HubConfiguration(); 

     Assembly thisAssembly = typeof(SignalRConfig).Assembly; 

     builder.RegisterHubs(thisAssembly); 

     var container = builder.Build(); 
     config.Resolver = new AutofacDependencyResolver(container); 


     app.UseAutofacMiddleware(container); 
     app.MapSignalR("/signalr", config); 
    } 
} 

這是迷上了這一行被添加到我的AssemblyInfo.cs

[assembly: OwinStartup(typeof(SignalRConfig))] 

但在其不工作因爲我的集線器沒有無參數的構造函數,並且無法解析依賴關係。我的假設是我正在創建一個新的ContainerBuilder(按照文檔),並且此實例沒有任何註冊。我實際上需要引用我的模塊傳遞的ContainerBuilder,該模塊知道我所有的註冊類型。我只是不知道該怎麼做。現有的IOC代碼從global.asax上的application_start運行,並且SignalRConfig同時運行。我不想將ContainerBuilder放在單身中,因爲它感覺髒,但我找不到任何其他解決方案。

下面是該版本號的我的NuGet包配置的部分等

<package id="Autofac" version="3.5.2" targetFramework="net451" /> 
    <package id="Autofac.Mvc4" version="3.1.0" targetFramework="net40" /> 
    <package id="Autofac.Owin" version="3.1.0" targetFramework="net451" /> 
    <package id="Autofac.SignalR" version="3.0.1" targetFramework="net451" /> 
    <package id="Autofac.WebApi" version="3.1.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.Mvc" version="4.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.SignalR" version="2.2.0" targetFramework="net451" /> 
    <package id="Microsoft.AspNet.SignalR.Core" version="2.2.0" targetFramework="net451" /> 
    <package id="Microsoft.AspNet.SignalR.JS" version="2.2.0" targetFramework="net451" /> 
    <package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.2.0" targetFramework="net451" /> 
    <package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.WebApi.Client" version="4.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.WebApi.Core" version="4.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net40" /> 
    <package id="Microsoft.Owin" version="3.0.0" targetFramework="net451" /> 
    <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net451" /> 
    <package id="Microsoft.Owin.Security" version="3.0.0" targetFramework="net451" /> 
    <package id="Owin" version="1.0" targetFramework="net451" /> 

回答

3

這聽起來像你混合遺產IIS新OWIN託管(OwinStartup)託管機制(Application_Start)和那將很難糾正。

如果您使用OWIN託管您的應用程序,我建議將整個啓動切換到OWIN(至少啓動邏輯),因此您不必嘗試同步對容器的訪問或傳遞信息。如果你願意,你仍然可以在Global.asax中保存其他事件處理程序(Application_Error等),只需將啓動邏輯統一到OWIN啓動類中即可。

通過將「圖層」分隔到不同的啓動類中,您仍然可以保持相當整潔。

public static class Startup 
{ 
    public static void Configuration(IAppBuilder app) 
    { 
    var container = DependencyConfiguration.Configure(app); 
    SignalRConfiguration.Configure(app, container); 
    MvcConfiguration.Configure(app, container); 
    } 
} 

public static class DependencyConfiguration 
{ 
    public static IContainer Configure(IAppBuilder app) 
    { 
    var builder = new ContainerBuilder(); 
    builder.RegisterHubs(typeof(SignalRConfiguration).Assembly); 
    var container = builder.Build(); 
    app.UseAutofacMiddleware(container); 
    return container; 
    } 
} 

public static class SignalRConfiguration 
{ 
    public static void Configure(IAppBuilder app, IContainer container) 
    { 
    var config = new HubConfiguration(); 
    config.Resolver = new AutofacDependencyResolver(container); 
    app.MapSignalR("/signalr", config); 
    } 
} 

...等等。重要的一點是,你已經擁有了所有的依賴項,並且首先添加了Autofac中間件。然後,您可以將容器傳遞給個別應用程序類型設置(就像您在SignalR中看到的那樣)。

然後引導整個事情與主啓動類:

[assembly: OwinStartup(typeof(Startup))] 

有一個很大的好處這一點。你避開了你遇到的競爭條件;您不需要嘗試同步或重新排序;你有很多控制權。如果你想要移植,它也爲你設置了一個更好的地方,因爲一切都是OWIN。

+0

感謝您的詳細解答。我會按照您的建議重構我的啓動代碼。 – RussellEast 2015-01-22 10:10:59

+1

工作,謝謝 – RussellEast 2015-01-22 11:19:36