2017-01-13 38 views
0

This guide似乎不适用于SimpleInjector。使用SimpleInjector获取HubContext

OWIN启动看起来是这样的:

container = new Container(); 
container.Options.DefaultScopedLifestyle = new ExecutionContextScopeLifestyle(); 

container.RegisterSingleton(() => new SimpleInjectorSignalRDependencyResolver(_container)); 
container.RegisterSingleton(() => 
    new HubConfiguration() 
    { 
     EnableDetailedErrors = true, 
     Resolver = _container.GetInstance<SimpleInjectorSignalRDependencyResolver>() 
    }); 

container.RegisterSingleton<IHubActivator, SimpleInjectorHubActivator>(); 
container.RegisterSingleton<IStockTicker,StockTicker>(); 
container.RegisterSingleton<HubContextAdapter<StockTickerHub, IStockTickerHubClient>>(); 
container.RegisterSingleton(() => GlobalHost.ConnectionManager); 
container.Verify(); 

GlobalHost.DependencyResolver = container.GetInstance<SimpleInjectorSignalRDependencyResolver>(); 

app.Use(async (context, next) => 
{ 
    using (container.BeginExecutionContextScope()) 
    { 
     await next(); 
    } 
}); 

app.MapSignalR(container.GetInstance<HubConfiguration>()); 

HubContextAdapter看起来是这样的:

public class HubContextAdapter<THub, TClient> 
    where THub : Hub 
    where TClient : class 
{ 
    private readonly IConnectionManager _manager; 

    public HubContextAdapter(IConnectionManager manager) 
    { 
     _manager = manager; 
    } 

    public IHubContext<TClient> GetHubContext() 
    { 
     return _manager.GetHubContext<THub, TClient>(); 
    } 
} 

而且SimpleInjectorSignalRDependencyResolver样子:

public class SimpleInjectorSignalRDependencyResolver : DefaultDependencyResolver 
{ 
    public SimpleInjectorSignalRDependencyResolver(IServiceProvider serviceProvider) 
    { 
     _serviceProvider = serviceProvider; 
    } 

    public override object GetService(Type serviceType) 
    { 
     return _serviceProvider.GetService(serviceType) ?? base.GetService(serviceType); 
    } 

    public override IEnumerable<object> GetServices(Type serviceType) 
    { 
     var @this = (IEnumerable<object>)_serviceProvider.GetService(
      typeof(IEnumerable<>).MakeGenericType(serviceType)); 

     var @base = base.GetServices(serviceType); 

     return @this == null ? @base : @base == null ? @this : @this.Concat(@base); 
    } 

    private readonly IServiceProvider _serviceProvider; 
} 

而且StockTicker样子:

public class StockTicker : IStockTicker 
{ 
    private readonly HubContextAdapter<StockTickerHub, IStockTickerHubClient> _context; 

    public StockTicker(HubContextAdapter<StockTickerHub, IStockTickerHubClient> context) 
    { 
     _context = context; 
    } 
} 

StockTicker蜱,并呼吁所有客户端更新客户端的方法不会被调用,也没有网络流量。

回答

0

SimpleInjector想要在验证后或在第一个GetInstance调用后实例化单例。这对SignalR和StockTicker来说还为时过早,并且在SimpleInjectorSignalRDependencyResolver是解析器之前需要使用GlobalHost.ConnectionManager的实例。

我选择了改变IConnectionManager的依赖是Lazy<IConnectionManager>IStockTicker的依赖是Lazy<IStockTicker>使注册成为类似如下:

container = new Container(); 
container.Options.DefaultScopedLifestyle = new ExecutionContextScopeLifestyle(); 

container.RegisterSingleton(() => new SimpleInjectorSignalRDependencyResolver(_container)); 
container.RegisterSingleton(() => 
    new HubConfiguration() 
    { 
     EnableDetailedErrors = true, 
     Resolver = _container.GetInstance<SimpleInjectorSignalRDependencyResolver>() 
    }); 

container.RegisterSingleton<IHubActivator, SimpleInjectorHubActivator>(); 
container.RegisterSingleton<IStockTicker,StockTicker>(); 
container.RegisterSingleton<Lazy<IStockTicker>>(() => new Lazy<IStockTicker>(() => container.GetInstace<IStockTicker>())); 
container.RegisterSingleton<HubContextAdapter<StockTickerHub, IStockTickerHubClient>>(); 
container.RegisterSingleton(() => new Lazy<IConnectionManager>(() => GlobalHost.ConnectionManager)); 
container.Verify(); 
相关问题