如何在ASP.NET 5(vNext)中设置SignalR Hub依赖注入?

时间:2015-08-21 22:29:34

标签: c# asp.net dependency-injection signalr asp.net-core

尝试使用作为ASP.NET 5(repo)一部分的SignalR-Server对我的SignalR Hub类进行依赖注入。我试图在this link的教程中解决这个问题,但鉴于GlobalHost不再可用,我似乎无法确定如何做到这一点。这就是我想要做的事情:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR();
    services.AddSingleton<IState, State>();
}

public void Configure(IApplicationBuilder app)
{
    app.UseSignalR();
}

MyHub.cs

public class MyHub : Hub
{
    public IState State { get; set; }

    // SignalR accepts this parameterless ctor
    public MyHub()
    {
    }

    // SignalR won't use this because it has a parameter
    public MyHub(IState state)
    {
        State = state;
    }
}

如何让SignalR-Server使用注入所需依赖项的MyHub(IState state)构造函数?

4 个答案:

答案 0 :(得分:1)

我设法通过在State中将IState类添加为Startup.ConfigureServices的单例,然后在我的Startup.cs上公开ServiceProvider属性来解决此问题类。从那里,我能够在我的SignalR Hub类的构造函数中GetRequiredService。它不是理想的解决方案,希望我能够调整它以使用构造函数/属性注入,因为平台到达RC。

这是我的代码:

<强> Startup.cs

public static IServiceProvider __serviceProvider;

public void ConfigureServices(IServiceCollection services)
{
    services.AddSignalR();
    services.AddSingleton<IState, State>();
    __serviceProvider = services.BuildServiceProvider();
}

public void Configure(IApplicationBuilder app)
{
    app.UseSignalR();
}

<强> MyHub.cs

public class MyHub : Hub
{
    public IState State { get; set; }

    public MyHub()
    {
        State = (IState) Startup.__serviceProvider.GetRequiredService(typeof (IState));
    }

    public override Task OnConnected()
    {
        State.Clients = Clients;
        State.Groups = Groups;
        return base.OnConnected();
    }
}

通过这种方式,我可以在IState内设置属性并调用方法,从MyHub开始实现对象,允许我将我的应用状态保存在内存中。

答案 1 :(得分:1)

最好的方法(对于Asp.Net 5)创建一个接收IServiceProvider的DefaultDependencyResolver的自定义解析器:

 public class CustomSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IServiceProvider _serviceProvider;

    public CustomSignalRDependencyResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override object GetService(Type serviceType)
    {
        var service = _serviceProvider.GetService(serviceType);

        return service ?? base.GetService(serviceType);
    }


}

然后在StartUp类

 public void ConfigureServices(IServiceCollection services)
    {

         services.AddSingleton<IState, State>();

        //... other services


        GlobalHost.DependencyResolver = new CustomSignalRDependencyResolver(services.BuildServiceProvider());

    }

答案 2 :(得分:0)

我简单地使用依赖项构建了构造函数。例如,我需要我的IUnitOfWork实例(在启动时配置)在集线器中。那是工作代码

[HubName("receipts")]
public class ReceiptsHub : Hub
{
    public IUnitOfWork<string> UnitOfWork { get; set; }

    public ReceiptsHub(IUnitOfWork<string> unitOfWork) : base()
    {
        UnitOfWork = unitOfWork;
    }

    public override Task OnConnected()
    {
        return base.OnConnected();
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        return base.OnDisconnected(stopCalled);
    }
}

答案 3 :(得分:0)

你非常接近。你只需要:

public class MyHub : Hub
{
    readonly IState _state;

    public MyHub(IState state)
    {
        _state = state;
    }
}