2017-01-13 16 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 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 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 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のインスタンスを取ることになります。

私はその登録は、以下のようになったLazy<IStockTicker>するIStockTickerLazy<IConnectionManager>と依存するIConnectionManagerへの依存を変更することにしました:

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(); 
関連する問題