Autofac – 带有OWIN的SignalR。 获取对ContainerBuilder的引用

我有一个使用Autofac的现有MVC 4应用程序,我有其他具有autofac模块的程序集。如果没有SignalR / autofac集成,我的应用程序就IOC而言是完美的。 我添加了SignalR集线器,我试图通过构造函数注入依赖项。 我已经按照文档并实现了代码示例。

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包配置的一部分,显示了版本号等

                      

听起来你正在将旧的IIS托管机制( Application_Start )与新的OWIN托管( OwinStartup )混合OwinStartup ,这将很难纠正。

如果您使用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))] 

这有很多好处。 你回避了你遇到的竞争条件; 你不需要尝试同步或重新排序东西; 你有很多控制权。 如果你想移植它,它还可以让你在ASP.NET vNext的更好位置,因为一切都是OWIN。