【问题标题】:SignalR cannot call client function when using StructureMap dependency resolverSignalR 在使用 StructureMap 依赖解析器时无法调用客户端函数
【发布时间】:2013-09-11 20:06:45
【问题描述】:

当我在我的 global.asax 中为 signalR 包含结构映射依赖解析器时,任何对客户端函数的调用都不再到达浏览器,尽管我可以在日志管道中看到它们。

这是我的 global.asax 的摘录:

var container = ObjectFactory.Container;

// Now configure SignalR, MVC, ASP.Net and SharpRepository

GlobalHost.HubPipeline.AddModule(new ErrorHandlingPipelineModule());
GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule());

// TODO: Work out why this breaks the connection between the server and the client.

GlobalHost.DependencyResolver = 
    ObjectFactory.GetInstance<IDependencyResolver>();
RouteTable.Routes.MapHubs();

DependencyResolver.SetResolver(
    new StructureMapDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = 
    new StructureMapDependencyResolver(container);
RepositoryDependencyResolver.SetDependencyResolver(
    new SharpRepository.Ioc.StructureMap.StructureMapDependencyResolver(container));

这里是结构映射解析器的实现:

public class StructureMapSignalRDependencyResolver 
    : DefaultDependencyResolver
{
    private readonly IContainer _container;

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

        _container = container;
    }

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

        try
        {
            result = 
                !serviceType.IsAbstract &&
                !serviceType.IsInterface &&
                serviceType.IsClass
                    ? _container.GetInstance(serviceType)
                    : (_container.TryGetInstance(serviceType) 
                        ?? base.GetService(serviceType));
        }
        catch (Exception ex)
        {
            Tracing.Error(
                "[StructureMapSignalRDependencyResolver]",
                 Tracing.SerializeException(ex));
        }

        if (result == null)
        {
            Tracing.Information(
                "[StructureMapSignalRDependencyResolver]",
                "Could retrieve object of type {0}",serviceType.ToString());
        }

        return result;
    }

    public override IEnumerable<object> GetServices(
        Type serviceType)
    {
        IEnumerable<object> result = null;

        try
        {
            result = _container.GetAllInstances(serviceType)
                .Cast<object>().Concat(
                    base.GetServices(serviceType));
        }
        catch (Exception ex)
        {
            Tracing.Error(
                "[StructureMapSignalRDependencyResolver]", 
                Tracing.SerializeException(ex));
        }

        if (result == null)
        {
            Tracing.Information(
                "[StructureMapSignalRDependencyResolver]", 
                "Could retrieve object of type {0}", serviceType.ToString());
        }

        return result;
    }

    public override void Register(Type serviceType, 
        Func<object> activator)
    {
        Tracing.Information(
            "[StructureMapSignalRDependencyResolver]", 
            "Registering object of type {0}", 
            serviceType.ToString());

        base.Register(serviceType, activator);
    }

    public override void Register(Type serviceType, 
        IEnumerable<Func<object>> activators)
    {
        Tracing.Information(
            "[StructureMapSignalRDependencyResolver]", 
            "Registering object of type {0}", 
            serviceType.ToString());

        base.Register(serviceType, activators);
    }
}

这里是 StructureMap Registry 的实现(还有更多,包括应用程序程序集)。

[RegistryOrder(Order = 6)]
public class SignalRRegistry : Registry
{
    public SignalRRegistry()
    {
        For<IDependencyResolver>().Singleton()
            .Use<StructureMapSignalRDependencyResolver>();
        For<IHubConnectionContext>().Singleton()
            .Use(GlobalHost.ConnectionManager
                .GetHubContext<BOSSHub>().Clients);     
    }

    //public void Configure()
    //{
    //    GlobalHost.DependencyResolver = 
    //        ObjectFactory.GetInstance<IDependencyResolver>();
    //    RouteTable.Routes.MapHubs();
    //}
}

我已回滚 Hub 类,使其不再具有依赖项; WhatDoIHave 的输出似乎有一些 Microsoft.AspNet.SignalR 条目,但没有任何具体关系。

我想知道我是否错过了注册表中的步骤?我在任何地方都没有例外;如果我从 global.asax 中注释掉 GlobalHost.DependencyResolver 行,它就会停止工作。

我希望有人可以与我分享一个适用于他们的 signalR 的 DI 实现。

非常感谢

更新:感谢您为我整理出错误的格式 - 非常感谢。

更新:我整理了一个显示问题的小型测试项目。老实说,我很惊讶我能够将它复制为我正在处理的应用程序,它非常庞大且复杂,有很多 StructureMap 的东西在进行。我已经上传到 GitHub:https://github.com/johnk27stars/SignalRTest.git - 感谢任何可以抽出时间看一看的人。

【问题讨论】:

  • 你能分享一个 zip 文件或 git 存储库中的最小项目吗?
  • 更新:我现在已将单数源代码包含在我的解决方案中,看看我是否能获得更多洞察力。我发现,当我使用 DI 容器时,signalR 似乎在管道中的某处丢失了它的主题集合,尽管消息看起来仍然不错,但它并没有建立任何订阅者。
  • 更新:我已上传到 GitHub:github.com/johnk27stars/SignalRTest.git - 感谢任何愿意花一分钟时间查看的人。
  • 也许是你的依赖解析器 impl。你的容器还没有一个吗?
  • 是的,我已经尝试过 nugget 包版本(即使它引用了 signalR 0.4),并且我还从我发现的 stackoverflow 复制了一些变体 - 全部使用结果相同。

标签: c# asp.net-mvc dependency-injection signalr structuremap


【解决方案1】:

在 Jeremy Miller 的一些诚实建议后,我们改用 AutoFac,它运行良好。

【讨论】:

    猜你喜欢
    • 2018-10-20
    • 2012-03-31
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多