SignalR 2.0使用Ninject注入接口

时间:2013-12-23 11:45:43

标签: .net dependency-injection ninject signalr

我有以下简单的Hub类来列出使用注入用户服务的用户。使用NinjectSignalRDependencyResolver的启动类。而且非常简单的客户端脚本。

[HubName("dashboardHub")]
public class DashboardHub : Hub
{
    private readonly IUserService _users;

    public DashboardHub(IUserService users)
    {
        _users = users;
    }

    public void Initialize()
    {
        var users = _users.ListUsers();

        Clients.All.UpdateStatus(users);
    }
}

startup.cs

  var kernel = new StandardKernel();
  var resolver = new NinjectSignalRDependencyResolver(kernel);

  var config = new HubConfiguration()
  {
        Resolver = resolver,
  };

  app.MapSignalR(config);

NinjectSignalRDependencyResolver

public class NinjectSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectSignalRDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
    }
}

的JavaScript

<script>
    $(function () {
        var dashboard = $.connection.dashboardHub;

        dashboard.client.updateStatus = function (users) {
            var elem= $('.userList');

            elem.html('');
            $.each(users, function (i, user) {
                parent.append("<p>" user.Name +  "<p>");
            });
        };

        $.connection.hub.start().done(function () {
            dashboard.server.initialize();
        });
    });
</script>

我在RegisterServices

中以标准方式注册Ninject接口
private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IUserService >().To<UserService>().InSingletonScope();

    ...
}

使用脚本打开客户端时。代码运行,没有生成异常或脚本错误。永远不会调用Dashboard的构造函数,也不会调用Initialize()方法 - 即使JavaScript中存在对象,方法也是如此。永远不会将用户列表填充为client.updateStatus永远不会被调用。

如果我向Hub类添加一个默认构造函数,那么调用它也是如此,而且Initialize方法也是如此 - 但是当私有IUserService变量为null时,它显然会被忽略。

public DashboardHub()
{
}

如何配置SignalR 2.0和Ninject以允许集线器具有依赖注入的构造函数参数?

1 个答案:

答案 0 :(得分:10)

实现这一目标的最简单方法是完全摆脱Custom Dependency解析器,而只是使用一个非常简单的IHubActivator。

startup.cs

public void Configuration(IAppBuilder app)
{
    app.MapSignalR();
}

Hubactivator.cs

public class HubActivator : IHubActivator
{
    private readonly IKernel container;

    public HubActivator(IKernel container)
    {
        this.container = container;
    }

    public IHub Create(HubDescriptor descriptor)
    {
        return (IHub)container.GetInstance(descriptor.HubType);
    }
}

RegisterServices

private static void RegisterServices(IKernel kernel)
{
    GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new HubActivator(kernel));    

    kernel.Bind<IUserService >().To<UserService>().InSingletonScope();

    ...
}

简单 - 一切正常,接口按照您的预期注入到构造函数中......