簡體   English   中英

使用簡單注射器將 controller 注入 SignalR 集線器

[英]Injecting controller into SignalR Hubs using Simple Injector

我想使用 Simple Injector 將 singleton controller 注入我的集線器。

我已經嘗試了以下方法,但我現在得到狀態 500 作為響應。

事件數據中心:

public class EventDataHub : Hub
{
    private static IEventDataController _dataController;
    
    public EventDataHub(IEventDataController dataController)
    {
        _dataController = dataController;
    }
    
    public void Subscribe(string signal)
    {
        _dataController.Subscribe(signal, Context.ConnectionId);
    }
}

啟動:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var container = new Container();
    
        var hybridLifestyle = Lifestyle.CreateHybrid(
                    lifestyleSelector: () => HttpContext.Current != null,
                    trueLifestyle: new WebRequestLifestyle(),
                    falseLifestyle: new LifetimeScopeLifestyle());
    
        container.Register<IEventDataController, EventDataController>(Lifestyle.Singleton);
        container.Register<IHub, EventDataHub>(hybridLifestyle);
    
        container.Verify();
    
        var activator = new SimpleInjectorHubActivator(container);
        
        GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);
    
        app.MapSignalR();
    }
}

集線器激活器:

public class SimpleInjectorHubActivator : IHubActivator
{
    private readonly Container _container;
    
    public SimpleInjectorHubActivator(Container container)
    {
        _container = container;
    }
    
    public IHub Create(HubDescriptor descriptor)
    {
        return (IHub)_container.GetInstance(descriptor.HubType);
    }
}

Subscribe方法似乎無法從客戶端訪問。 執行集線器構造函數。

異常堆棧:

[MissingMethodException:沒有為此對象定義無參數構造函數]
System.RuntimeTypeHandle.CreateInstance(RuntimeType 類型, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal&ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(布爾 publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark 和 stackMark)+113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +206 System.Activator.CreateInstance(Type type, Boolean nonPublic) +83 System.Activator.CreateInstance(Type type) +11

編輯:

將 DI 配置從 Startup.cs 移動到 global.asax 會引發以下異常:

[ArgumentNullException:值不能為 null。 參數名稱:s] System.IO.StringReader..ctor(String s) +11377176
Microsoft.AspNet.SignalR.Json.JsonSerializerExtensions.Parse(JsonSerializer 序列化程序,字符串 json)+63
Microsoft.AspNet.SignalR.Hubs.HubRequestParser.Parse(字符串數據,JsonSerializer 序列化器)+21
Microsoft.AspNet.SignalR.Hubs.HubDispatcher.OnReceived(IRequest request, String connectionId, String data) +40
Microsoft.AspNet.SignalR.<>c__DisplayClass64_1.b__5() +34 Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethod(Func`1 func) +28
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任務任務)+92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務任務)+58

我終於找到了問題:

container.Verify()正在破壞IHubActivator的注冊。 因此必須在之后調用它,或者永遠不要調用它。

此外,我刪除了IHub的容器注冊,因為它現在可以正常工作。 (我添加它是因為container.Register<IEventDataController, EventDataController>(Lifestyle.Singleton)當時沒有工作並且以某種方式修復了它)

所以我在 Startup.cs 中的最終代碼如下所示:

public void Configuration(IAppBuilder app)
{
    var container = new Container();

    container.Register<IEventDataController, EventDataController>(Lifestyle.Singleton);

    var activator = new SimpleInjectorHubActivator(container);
    GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => activator);

    app.MapSignalR();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM