Zgodnie z postem this, powinno być możliwe wstrzykiwanie zależności między aplikacjami SignalR (choć z pewnymi ograniczeniami, takimi jak problem z metodą OnDisconnected()). W moim przypadku jest to ASP Web API (nie MVC) i nie działa z jakiegoś powodu.Zależność Simple Injector per-web-api-request od SignalR hub
Oto odpowiednie części:
container.RegisterWebApiControllers(httpConfiguration);
container.RegisterWebApiRequest<DbContext, MyDbContext>();
container.RegisterWebApiRequest<ISampleRepository, SampleRepository>(); //DbContext injected to SampleRepository
//Enable injections to SignalR Hubs
var activator = new SimpleInjectorHubActivator(container);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator),() => activator);
Klasa ta umożliwia wstrzyknąć do piast:
public class SimpleInjectorHubActivator : IHubActivator
{
private readonly Container _container;
public SimpleInjectorHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.GetInstance(descriptor.HubType);
}
}
i piasty sam:
[HubName("sample")]
public class SampleHub : Hub
{
public ActiveBetsHub(ISampleRepository repository)
{
}
//Irrelevant methods here. OnDisconnected() NOT implemented!
}
Przy tej konfiguracji otrzymuję wyjątek:
No registration for type SampleHub could be found and
an implicit registration could not be made.
The ISampleRepository is registered as 'Web API Request'
lifestyle, but the instance is requested outside the context of a Web API Request.
Co jest oczekiwane, jak rozumiem. Jednak mam dokładnie taki sam wyjątek przy zmianie stylu życia repozytorium Transient:
var transientHybrid = Lifestyle.CreateHybrid(() => HttpContext.Current != null, new WebApiRequestLifestyle(), Lifestyle.Transient);
container.Register<ISampleRepository, SampleRepository>(transientHybrid);
Podejrzewam, że problem może leżeć w HttpContext.Current != null
czeku, który nie działa dla Web API w ten sam sposób jak dla MVC.
SignalR 2,2
Proste wtryskiwacza 2.8.3
Czego brakuje?
UPDATE:
To stos ślad na jak SignalR tworzy Piasty:
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.Container.GetInstance(Type serviceType)
at MyWebAbi.WebApiApplication.SimpleInjectorHubActivator.Create(HubDescriptor descriptor) in Global.asax.cs:line 108
at Microsoft.AspNet.SignalR.Hubs.DefaultHubManager.ResolveHub(String hubName)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.CreateHub(IRequest request, HubDescriptor descriptor, String connectionId, StateChangeTracker tracker, Boolean throwIfFailedToCreate)
Zatem właściwym rozwiązaniem byłoby wykorzystanie ExecutionContextScope
Przez Piasty ale ten zakres musi być wyraźnie zamknięty, co Sprawia, że sprawy są bardziej skomplikowane ...
Dziękuję bardzo za odpowiedź @Steven. Kiedy powiesz "i upewnij się, że taki zakres kontekstu wykonania zostanie uruchomiony, zanim twój koncentrator zostanie rozwiązany." masz na myśli używanie container.BeginExecutionContextScope()? Ponieważ zakres ten wymaga wyraźnego usunięcia, jak radziłbyś zaimplementować tę część, gdyby nie był używany wzorzec CommandHandler. A także czy firma powinna być zarejestrowana jako WebApiRequest Lifestyles? Dzięki! –
@IljaS. Naprawdę nie mogę odpowiedzieć na to pytanie. Nie wiem jak wygląda twoja implementacja, w którym momencie otrzymasz ślad stosu (i moje doświadczenie SignalR również nie ma). Spróbuj zaktualizować swoje pytanie, dodając więcej kodu i kompletny ślad stosu. Przyjrzę się. – Steven
Nie ma zbyt wiele w realizacji. Dla uproszczenia sake pozwala na stwierdzenie, że jest to bardzo prosta aplikacja WebApi z 1 klasą Repository, do której wstrzykiwany jest DbContext. 1 Hub, w którym chciałbym wstrzyknąć tę klasę Repository. I to wszystko. Dodałem ścieżkę stosu do wywołania Hub SignalR. Nie wiem, co jeszcze dodać. –