C# Autofac-带OWIN的信号机。获取对ContainerBuilder的引用
我有一个使用Autofac的现有MVC4应用程序,我还有其他程序集,其中包含Autofac模块。没有信号器/autofac集成,就IOC而言,我的应用程序工作得非常完美。我已经添加了信号集线器,我正试图通过构造函数将依赖项注入其中。我遵循了文档并从中实现了代码示例 这将导致以下类别:C# Autofac-带OWIN的信号机。获取对ContainerBuilder的引用,c#,asp.net-mvc-4,signalr,autofac,C#,Asp.net Mvc 4,Signalr,Autofac,我有一个使用Autofac的现有MVC4应用程序,我还有其他程序集,其中包含Autofac模块。没有信号器/autofac集成,就IOC而言,我的应用程序工作得非常完美。我已经添加了信号集线器,我正试图通过构造函数将依赖项注入其中。我遵循了文档并从中实现了代码示例 这将导致以下类别: public class SignalRConfig { public void Configuration(IAppBuilder app) { var builder = ne
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);
}
}
这与添加到my AssemblyInfo.cs的这一行连接
[assembly: OwinStartup(typeof(SignalRConfig))]
但它在运行时不起作用,因为我的集线器没有无参数构造函数,并且它无法解析依赖关系。我的假设是,我正在创建一个新的ContainerBuilder(根据文档),并且这个实例上没有注册任何内容。实际上,我想要的是对ContainerBuilder的引用,它在我的模块中传递,这些模块知道我所有注册的类型。我只是不知道怎么做。现有IOC代码从global.asax上的应用程序_start运行,同时运行SignalConfig。我不想把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" />
这听起来像是将旧的IIS托管机制(
应用程序启动
)与新的OWIN托管机制(OwinStartup
)混合在一起,这将很难纠正
如果您使用OWIN托管应用程序,我建议将整个启动切换到OWIN(至少是启动逻辑),这样您就不必尝试同步对容器的访问或传递信息。您仍然可以在Global.asax中保留其他事件处理程序(Application\u 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中间件。然后,您可以将容器传递给各个应用程序类型设置中使用的容器(就像您在signar中看到的那样)
然后用主启动类引导整个过程:
[assembly: OwinStartup(typeof(Startup))]
这有很多好处。你避开了你所遇到的比赛条件;你不需要尝试同步或重新排序;你有很多控制权。如果您想移植ASP.NET vNext,它还为您提供了一个更好的位置,因为一切都已就绪。谢谢您的详细回答。我将按照您的建议重新调整我的启动代码。