2017-01-13 9 views
0

This guide не работает для SimpleInjector.Получить HubContext с помощью SimpleInjector

Мой 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>()); 

And The 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, и он примет экземпляр GlobalHost.ConnectionManager до того, как SimpleInjectorSignalRDependencyResolver является преобразователем.

Я решил изменить зависимость от 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();