SignalR结构图依赖项解析器(为Microsoft.AspNet.SignalR.Messaging.IMessageBus指定)

时间:2015-01-30 10:31:11

标签: signalr structuremap

我该如何解决此错误?

版本

Microsoft.AspNet.SignalR.Core 2.2.0,structuremap 3.1.4.143

global.asax signalR依赖解析

// SIGNALR DEPENDENCY RESOLVER
        GlobalHost.DependencyResolver = new StructureMapSignalRDependencyResolver(Container ?? ObjectFactory.Container);

StructureMapSignalRDependencyResolver

public class StructureMapSignalRDependencyResolver : DefaultDependencyResolver
{
    private readonly IContainer _container;
    public StructureMapSignalRDependencyResolver(IContainer container)
    {
        _container = container;
    }

    public override object GetService(Type serviceType)
    {
        object service = null;
        //Below is a key difference between this StructureMap example, GetInstance is used for concrete classes.
        if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
        {
            //If the type is a concrete type we get here...
            service = _container.GetInstance(serviceType);
        }
        else
        {
            // Non concrete resolution which uses the base dependency resolver if needed.
            service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
        }
        return service;
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        var objects = _container.GetAllInstances(serviceType).Cast<object>();
        return objects.Concat(base.GetServices(serviceType));
    }
}

erorr

没有注册默认实例,无法自动确定类型为“Microsoft.AspNet.SignalR.Messaging.IMessageBus”

没有为Microsoft.AspNet.SignalR.Messaging.IMessageBus指定配置

1。)新的AckSubscriber( IMessageBus的默认值 IAckHandler的默认值) 2.)Microsoft.AspNet.SignalR.Infrastructure.AckSubscriber 3.)Microsoft.AspNet.SignalR.Infrastructure.AckSubscriber的实例 4.)Container.GetInstance(Microsoft.AspNet.SignalR.Infrastructure.AckSubscriber)

enter image description here

enter image description here

4 个答案:

答案 0 :(得分:5)

首先尝试从基类解析。

    public override object GetService(Type serviceType)
    {
        if (serviceType == null)
            return null;

        var service = base.GetService(serviceType);
        if (service != null) return service;

        return (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
            ? container.GetInstance(serviceType)
            : container.TryGetInstance(serviceType);
    }

答案 1 :(得分:1)

上面的@ajm回答绕过了我的错误,但是我发现没有调用我的客户端方法。

事实证明SignalR.Infrastructure.PrincipalUserIdProvider正在解决,而不是我的自定义IUserIdProvider所以我必须先通过添加容器检查来稍微修改他的答案。

    public override object GetService(Type serviceType)
    {
        if (serviceType == null)
            return null;

        var service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
        if (service != null) return service;

        return (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
            ? _container.GetInstance(serviceType)
            : _container.TryGetInstance(serviceType);
    }

如果您使用StructureMap 3,则仍需要辅助容器检查,因为TryGetInstance()返回null具体类型。

答案 2 :(得分:0)

我发现了暂时的,但错误仍在继续 我如何注册这个{Name =“AckSubscriber”FullName =“Microsoft.AspNet.SignalR.Infrastructure.AckSubscriber”}

临时解决方案是try catch,在catch return null

    public override object GetService(Type serviceType)
    {

        try
        {
            object service = null;
            //Below is a key difference between this StructureMap example, GetInstance is used for concrete classes.
            if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
            {
                //If the type is a concrete type we get here...
                service = _container.GetInstance(serviceType);
            }
            else
            {
                // Non concrete resolution which uses the base dependency resolver if needed.
                service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
            }
            return service;
        }
        catch (Exception exc)
        {
            return null;
        }
    }

答案 3 :(得分:0)

使用基于Ninject的解析器,我也遇到了类似的问题。在这种情况下,解决方案是确保Ninject与IDependencyResolver具有绑定,类似于此。

var resolver = new NinjectResolver(kernel);
kernel.Bind<IDependencyResolver>().ToConstant(resolver);
GlobalHost.DependencyResolver = resolver;

AckSubscriber有2个构造函数。

public AckSubscriber(IDependencyResolver resolver)
public AckSubscriber(IMessageBus messageBus, IAckHandler ackHandler)

由于某种原因,它似乎不是在尝试通过依赖关系解析器创建此类,而是在尝试通过底层IOC容器创建此类。因为所有这些类的绑定都在DefaultDependencyResolver中,所以容器不知道它们是什么,因此会出错。通过为IDependencyResolver指定绑定,它可以使用第一个构造函数并按预期工作。