6

HttpContextBaseSignalR ハブに挿入しようとしています:

public class EventHub : Hub, IDisconnect
{
    private readonly HttpContextBase _httpContextBase;

    public EventHub(HttpContextBase httpContextBase)
    {
        _httpContextBase = httpContextBase;
    }

    [...]
}

登録コードは次のようになります。

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();
}

そして、私が得ているエラーは次のとおりです。

[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

私はautofacとSignalRを使い始めたばかりで、少し行き詰まっています。SOに関する関連トピックはどれも役に立ちませんでした。私が間違っていることについて何か考えはありますか?

4

1 に答える 1

5

問題は次の行です。

builder.RegisterModule(new AutofacWebTypesModule());

例外メッセージは、解決中にタグ付けされた有効期間スコープから何かを解決しようとしていることを示していますhttpRequest。何かを登録すると、Autofac で次のような登録が得られますInstancePerHttpRequest()

// These two are roughly equivalent:
builder.RegisterType<SomeType>().InstancePerHttpRequest();
builder.RegisterType<SomeType>().InstancePerMatchingLifetimeScope("AutofacWebRequest");

のソースを見るとAutofacWebTypesModule、Web 抽象化 (HttpContextBase探しているものなど) が として登録されInstancePerHttpRequestます。

さらに、 の動作を見るとAutofac.Integration.Mvc.AutofacDependencyResolver、リクエスト中にタイプを解決するたびに、 でタグ付けされた、ネストされた名前付きの新しい有効期間スコープが作成されhttpRequestます。これにより、その魔法を持つことができますInstancePerHttpRequest

SignalR.Autofac使用しているライブラリがhereであり、NuGetのライブラリでもあるという前提の下で、 を見て、SignalR.Autofac.AutofacDependencyResolverサービス解決のためにそのようなネストされた/名前付きの有効期間スコープが作成されていません

したがって、Autofac がHttpContextBase依存関係を解決しようとすると、タグ付けされたスコープが見つからhttpRequestず (存在しないため)、表示されているエラーが発行されます。

これには簡単な答えはありません。ネストされたスコープは、基本的に実際の Web 要求のhttpRequestには存在できないため、実際には重要です。これにより、「安全」になります。Web コンテキストがない場合 (アプリケーションの起動時など) を取得できません。HttpContextBase

を注入する必要があり、1 つの Web 要求に対してのみ有効HttpContextBaseであると確信しているEventHub場合 (私は SignalR の専門家ではないので、ご容赦ください)、次のいずれかを行う必要があることを意味します。

  • この問題の修正を SignalR.Autofac プロジェクトにリクエストしてください。
  • MVC リゾルバーと同じように処理する独自のカスタム SignalR.Autofac.AutofacDependencyResolver を実装します。

実際に作業を行って自分でテストしない限り、それを達成する方法について具体的なガイダンスを提供することはできません. この演習は読者に任せます。

于 2012-10-09T23:34:13.070 に答える