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 包
我有一个关于信号器(版本 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 包