繁体   English   中英

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

[英]How can I set up SignalR Hub Dependency Injection in ASP.NET 5 (vNext)?

尝试使用作为 ASP.NET 5 ( repo ) 一部分的 SignalR-Server 对我的 SignalR Hub 类进行依赖注入。 我试图从本链接的教程中弄清楚这一点,但鉴于GlobalHost不再可用,我似乎无法确定如何做到这一点。 这是我想要做的:

启动文件

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

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

我的中心

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)构造函数注入所需的依赖项?

最好的方法(对于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);
    }


}

然后在启动类上

 public void ConfigureServices(IServiceCollection services)
    {

         services.AddSingleton<IState, State>();

        //... other services


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

    }

你很亲密 您只需:

public class MyHub : Hub
{
    readonly IState _state;

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

好。 现在,我使用了Autofac ,但我不确定它是否已集成ASP.NET 5。 但是,如果(目前)仅针对.NET 4.6,则应该没问题。

我刚刚发布了此存储库 ,其中包含使用SignalR和Autofac进行依赖项注入的基本项目设置。

现在,我进行了依赖项注入设置,以实现以下目的:

  • 能够将依赖项注入我的中心

  • 能够获取我的集线器的上下文以便在不使用GlobalHost情况下从集线器外部发送给客户端(它在.NET 5中不再可用,但也不应使用,因为它是静态的全局对象)

我希望您能够成功设置项目(即使我认为您不能将DNX保留在构建选项中,因为Autofac尚未准备好.NET 5库。

我希望这有帮助! 祝你好运!

https://github.com/radu-matei/SignalRDependencyInjection

编辑:如果您想使用NInject(并且如果要定位DNX ,则可以构建自己的依赖项解析器,则可以从SignalR的官方人员(实际上是从编写SignalR的人员那里)遵循此存储库:

https://github.com/DamianEdwards/NDCLondon2013/tree/master/DependencyInjection

在此演示中,他们使用NInject创建了自己的依赖关系解析器,因此,如果您有NInject库,则对DNX定位不会有任何问题。

更新:在阅读了有关ASP.NET 5依赖注入的一些知识之后,看来它是以统一的方式完成的。 如果您没有看过这篇文章,即使它没有专门显示SignalR DI,我也推荐它。

通过在Startup.ConfigureServices IState State类添加为IState的Singleton,然后在Startup.cs类上公开提供ServiceProvider属性,我设法解决了这一问题。 从那里,我能够GetRequiredService我SignalR集线器类的构造函数中。 这不是理想的解决方案,希望当平台达到RC时,我将能够对其进行调整以使用构造函数/属性注入。

这是我的代码:

启动文件

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 ,让我坚持在内存中我的应用程序的状态。

我只是简单地使构造函数具有依赖关系。 例如,我需要中心中的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);
    }
}

在 .NET 5 中,您可以直接解析IServiceProvider ,然后您可以获得所需的服务。 请检查以下代码:

public class MyHub : Hub
{
    public IState State { get; set; }
    private readonly IServiceProvider _serviceProvider;
    public MyHub(IServiceProvider serviceProvider)
    {
        _serviceProvider=serviceProvider;
        State = _serviceProvider.GetRequiredService<IState>();
    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM