我们有一个复杂的应用程序,集线器分布在多个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;
}
但如上所述,它似乎甚至没有被召唤。
答案 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);
}
}
}