SIgnalR - 已添加具有相同键的项目

SIgnalR - An item with the same key has already been added

我有一个关于信号器(版本 1.2.2。我无法更新 toto 2+)/autofac/Nunit 实现的问题。我正在使用带有 WCF 服务的 MVC 客户端,whixh 将通知推送到客户端。当我 运行 使用 Web 客户端和服务的应用程序时,一切都按预期工作。当我每次尝试创建 hubcontext

时都尝试通过 NUnit 测试我的服务
GlobalHost.ConnectionManager.GetHubContext<ProductHub>()

我得到

An item with the same key has already been added.

这里是完整的堆栈跟踪

   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at Microsoft.AspNet.SignalR.Hubs.ReflectedHubDescriptorProvider.BuildHubsCache()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at System.Lazy`1.get_Value()
   at Microsoft.AspNet.SignalR.Hubs.ReflectedHubDescriptorProvider.TryGetHub(String hubName, HubDescriptor& descriptor)
   at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.c__DisplayClass1.b__0(IHubDescriptorProvider p)
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.GetHub(String hubName)
   at Microsoft.AspNet.SignalR.Hubs.HubManagerExtensions.EnsureHub(IHubManager hubManager, String hubName, IPerformanceCounter[] counters)
   at Microsoft.AspNet.SignalR.Infrastructure.ConnectionManager.GetHubContext(String hubName)
   at Microsoft.AspNet.SignalR.Infrastructure.ConnectionManager.GetHubContext[T]()

这里是global.asax服务文件

中的autofac和signalr注册
        protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
        var builder = new ContainerBuilder();
        builder.RegisterType<Product_WCF_Service>().AsSelf();
        builder.RegisterType<DbFactory>().As<IDbFactory>();
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
        builder.RegisterAssemblyTypes(
            new[] {
                typeof(ProductService).Assembly
            })
            .Where(t => t.Name.EndsWith("Service"))
            .AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(
            new[] {
                typeof(ProductRepository).Assembly
            })
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces();

        builder.RegisterType<ProductHub>().ExternallyOwned();    
        var container = builder.Build();
        container.Resolve<IUnitOfWork>();
        container.Resolve<IDbFactory>();
        GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
        AutofacHostFactory.Container = container;
        AutoMapperConfiguration.Configure();
    }

我的服务实现

public class Product_WCF_Service : IProduct_WCF_Service
{
    IUnitOfWork UnitOfWork;
    IProductService ProductService;

    public Product_WCF_Service(IUnitOfWork unitOfWork, IProductService productService)
    {
        this.ProductService = productService;
        this.UnitOfWork = unitOfWork;
    }

}

我的 NUnit 测试导致异常被抛出

[TestFixture]
public class WCF_Product_Service_Tests
{
    private Mock<IProduct_WCF_Service> ProductWCFService;
    private Mock<IUnitOfWork> UnitOfWork;
    private Mock<IProductService> ProductService;
    public WCF_Product_Service_Tests()
    {
        this.ProductWCFService = new Mock<IProduct_WCF_Service>();
        this.UnitOfWork = new Mock<IUnitOfWork>();
        this.ProductService = new Mock<IProductService>();
    }

    [Test]
    public void RetreiveDataFromWCF_Service()
    {
        byte commitStatus = 1;
        string response = string.Empty;
        var service = new Product_WCF_Service(this.UnitOfWork.Object, this.ProductService.Object);
        service.CreateProduct("", out response, out commitStatus);
    }}

这让我发疯,因为我根本无法测试我的服务!

好吧,我四处寻找,终于找到了解决办法。我把它留在这里以防万一有人觉得有用

在注册 autofac 时我启用了 属性 注入

                        var signalRConfig = new HubConfiguration();
        var builder = new ContainerBuilder();
        builder.RegisterType<ServiceHub>().ExternallyOwned(); // SignalR hub registration
        builder.Register(i => signalRConfig.Resolver.Resolve<IConnectionManager>().GetHubContext<ServiceHub>()).ExternallyOwned();
        builder.RegisterType<Product_WCF_Service>().AsSelf();
        builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerLifetimeScope();
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
        builder.RegisterAssemblyTypes(
            new[] {
                typeof(ProductService).Assembly
            })
            .Where(t => t.Name.EndsWith("Service"))
            .AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(
            new[] {
                typeof(ProductRepository).Assembly
            })
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces();

        builder.RegisterType<Product_WCF_Service>()
            .PropertiesAutowired();
        var container = builder.Build();
        signalRConfig.Resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
        signalRConfig.EnableCrossDomain = true;
        RouteTable.Routes.MapHubs(signalRConfig);
        AutofacHostFactory.Container = container;
        AutoMapperConfiguration.Configure();

在我的服务中,我在

中将 hubcontext 添加为 属性
public class Product_WCF_Service : IProduct_WCF_Service{

    IUnitOfWork UnitOfWork;
    IProductService ProductService;
    public IHubContext InstanceHubContext { get; set; }

    public Product_WCF_Service(IUnitOfWork unitOfWork, IProductService productService)
    {
        this.ProductService = productService;
        this.UnitOfWork = unitOfWork;
    }

它按预期工作了!我现在可以像往常一样访问 hubcontext

this.InstanceHubContext.Clients.All.onNotSavedProduct(message);

当然你还需要 Autofac.Integration.SignalR 和 Autofac.Integration.Wcf 包