Asp.Net SignalR DependencyResolver无法解析集线器

时间:2015-05-11 16:24:50

标签: c# asp.net asp.net-mvc asp.net-mvc-4 signalr

我们有一个复杂的应用程序,集线器分布在多个dll上。完整的应用程序使用DI和LightCore。现在我们面临的问题是SignalR似乎没有使用我们编写的DependencyResolver适配器。

我们尝试了两种不同的方法来注入自定义IDependencyResolver:

GlobalHost.DependencyResolver = new LightCoreSignalRDependencyResolver();

var hc = new HubConfiguration(Resolver = new LightCoreSignalRDependencyResolver()); 
app.MapSignalR(hc);

在这两种情况下,创建集线器时都不会调用我们的解析程序。更糟糕的是,我们得到的例外是集线器没有无参数构造函数。

我们还做了一个简短的测试,只需将自定义IHubActivator注入DefaultDependencyResolver。结果相同。根本不使用HubActivator - 至少我们不会遇到断点和日志条目。

有人知道这里会出现什么问题吗?

(在MVC和WebApi中,自定义依赖项解析器按预期工作)

使用构建器帮助程序注册集线器:

builder.Register<Hubs.LoggingHub, Hubs.LoggingHub>();

依赖性解析器如下所示:

public class LightCoreSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IContainer _container;

    public LightCoreSignalRDependencyResolver(IContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        // IDependencyResolver implementations must not throw an exception 
        // but return null if type is not registered
        catch (RegistrationNotFoundException registrationNotFoundException)
        {
            return base.GetService(serviceType);
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return  _container.ResolveAll(serviceType).Concat(base.GetServices(serviceType));
        }
        // IDependencyResolver implementations must not throw an exception 
        // but return an empty object collection if type is not registered
        catch (RegistrationNotFoundException registrationNotFoundException)
        {
            return base.GetServices(serviceType);
        }
    }
}

Hub构造函数如下所示:

这个与默认解析器一起使用,并使用我们的内部Bootstrapper来解析依赖关系。 (丑陋但有效的方式 - 显示依赖关系可以解决)

    public RobotControlHub()
    {
        _Publisher = Booty.Container.Resolve<IPublisher>();
        _MessageService = Booty.Container.Resolve<IRobotMessageRepectionService>();
        _CommandsService = Booty.Container.Resolve<IRobotGenericCommandsService>();
        _ConnectionsMapping = Booty.Container.Resolve<IRobotConnectionMappingRepository>();
    }

这是在SignalR中使用我们的Resolver时我们期望被调用的构造函数。

    public RobotControlHub(
        IRobotConnectionMappingRepository connectionsMapping, 
        IRobotGenericCommandsService commandsService,
        IRobotMessageRepectionService messageService,
        IPublisher publisher)
    {
        _Publisher = publisher;
        _MessageService = messageService;
        _CommandsService = commandsService;
        _ConnectionsMapping = connectionsMapping;
    }

但如上所述,它似乎甚至没有被召唤。

1 个答案:

答案 0 :(得分:1)

有时候睡个好觉并忘掉这个问题是件好事。第二天早上,您查看代码并发现缺少“覆盖”。 正确的代码:

public class LightCoreSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IContainer _container;

    public LightCoreSignalRDependencyResolver(IContainer container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public **override** object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        // IDependencyResolver implementations must not throw an exception 
        // but return null if type is not registered
        catch (RegistrationNotFoundException registrationNotFoundException)
        {
            return base.GetService(serviceType);
        }
    }

    public **override** IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return  _container.ResolveAll(serviceType).Concat(base.GetServices(serviceType));
        }
        // IDependencyResolver implementations must not throw an exception 
        // but return an empty object collection if type is not registered
        catch (RegistrationNotFoundException registrationNotFoundException)
        {
            return base.GetServices(serviceType);
        }
    }
}