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

时间:2018-01-09 12:19:29

标签: wcf asp.net-mvc-4 signalr nunit autofac

我遇到了有关信号器(版本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);
    }}

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

1 个答案:

答案 0 :(得分:0)

好的,我搜索了一下,最后我找到了解决方案。我把它留在这里以防有人发现这个有用的

注册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包