Fra*_*ier 6 c# dependency-injection autofac asp.net-mvc-3 signalr
我正在尝试HttpContextBase在我的SignalR集线器中注入一个:
public class EventHub : Hub, IDisconnect
{
private readonly HttpContextBase _httpContextBase;
public EventHub(HttpContextBase httpContextBase)
{
_httpContextBase = httpContextBase;
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
注册码如下所示:
private static void InitAutofac()
{
var builder = new ContainerBuilder();
var assembly = typeof (MvcApplication).Assembly;
builder.RegisterControllers(assembly).PropertiesAutowired();
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterFilterProvider();
builder.RegisterAssemblyTypes(assembly)
.Where(InterfaceBasedInjectedClasses())
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(assembly)
.Where(InterfaceLessInjectedClasses())
.InstancePerLifetimeScope();
builder.RegisterType<SurvivalContainer>().InstancePerLifetimeScope();
builder.RegisterType<EventHub>().InstancePerLifetimeScope();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalHost.DependencyResolver = new SignalR.Autofac.AutofacDependencyResolver(container);
RouteTable.Routes.MapHubs();
}
Run Code Online (Sandbox Code Playgroud)
而我得到的错误是:
[DependencyResolutionException:从请求实例的作用域中看不到具有匹配'httpRequest'的标记的作用域.这通常表示注册为每HTTP请求的组件正被SingleInstance()组件(或类似场景)重新请求.在Web集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,从不从容器本身请求]
堆栈跟踪:
Autofac.Core.Lifetime.MatchingScopeLifetime.FindScope(ISharingLifetimeScope mostNestedVisibleScope) +160
Autofac.Core.Resolving.InstanceLookup..ctor(IComponentRegistration registration, IResolveOperation context, ISharingLifetimeScope mostNestedVisibleScope, IEnumerable`1 parameters) +57
Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) +102
Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) +64
Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +164
Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) +14
Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance) +70
Autofac.ResolutionExtensions.TryResolve(IComponentContext context, Type serviceType, Object& instance) +70
SignalR.Autofac.AutofacDependencyResolver.GetService(Type serviceType) in D:\etc\Dev\SignalR.Autofac\AutofacDependencyResolver.cs:30
SignalR.Hubs.DefaultHubActivator.Create(HubDescriptor descriptor) +60
SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName) +27
SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, TrackingDictionary state, Boolean throwIfFailedToCreate) +445
SignalR.Hubs.HubDispatcher.OnReceivedAsync(IRequest request, String connectionId, String data) +246
SignalR.<>c__DisplayClass6.<ProcessRequestAsync>b__4(String data) +29
SignalR.Transports.ForeverTransport.ProcessSendRequest() +63
SignalR.Transports.ForeverTransport.ProcessRequestCore(ITransportConnection connection) +70
SignalR.Transports.ForeverTransport.ProcessRequest(ITransportConnection connection) +5
SignalR.PersistentConnection.ProcessRequestAsync(HostContext context) +560
SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context) +120
SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase context) +422 SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +68
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Run Code Online (Sandbox Code Playgroud)
我刚刚开始使用autofac和SignalR,我发现自己有点陷入困境.SO上的相关主题都没有帮助.关于我做错了什么的任何想法?
问题是这一行:
builder.RegisterModule(new AutofacWebTypesModule());
Run Code Online (Sandbox Code Playgroud)
异常消息表明,在解析期间,正在尝试从标记的生命周期范围中解析某些内容httpRequest.当您注册时,您会在Autofac中获得以下注册InstancePerHttpRequest():
// These two are roughly equivalent:
builder.RegisterType<SomeType>().InstancePerHttpRequest();
builder.RegisterType<SomeType>().InstancePerMatchingLifetimeScope("AutofacWebRequest");
Run Code Online (Sandbox Code Playgroud)
如果你看一下AutofacWebTypesModule它的来源,就会注册网络抽象(比如HttpContextBase,你正在寻找的东西)InstancePerHttpRequest.
此外,如果查看工作方式Autofac.Integration.Mvc.AutofacDependencyResolver,无论何时在请求期间解析类型,它都会创建一个新的嵌套命名生命周期范围,标记为httpRequest.这可以让你拥有那种魔力InstancePerHttpRequest.
假设SignalR.Autofac您使用的库是这里的库,也是NuGet上的库,查看SignalR.Autofac.AutofacDependencyResolver,没有为服务解析创建这样的嵌套/命名生命周期范围.
因此,当Autofac尝试解析HttpContextBase依赖关系时,它无法找到该httpRequest标记范围(因为它不存在)并发出您看到的错误.
对此没有简单的答案.嵌套httpRequest范围实际上很重要,因为它基本上不能存在于真实Web请求之外.它使它"安全" - HttpContextBase如果没有Web上下文(例如,在应用程序启动时),则无法获得.
如果你需要注射一个HttpContextBase并且你确定你的EventHub生活只适用于一个网络请求就是这样(我不是SignalR的人,所以请耐心等待),这意味着你需要:
如果没有真正完成工作并自己测试,我无法真正提供有关如何实现这一目标的具体指导.这个练习留给读者.