Se la nostra applicazione sfrutta Ninject e utilizza la tecnica della dependency injection, probabilmente ci troveremo nella situazione in cui, anche nell'ambito di un Hub di ASP.NET SignalR, abbiamo bisogno di iniettare le dipendenze tramite il costruttore:
public class CustomersHub : Hub { private ICustomerRepository _repository; public CustomersHub(ICustomerRepository repository) { if (repository == null) throw new ArgumentNullException("repository"); _repository = repository; } // ... }
In condizioni normali, questo Hub non è utilizzabile: ASP.NET SignalR, infatti, utilizza un dependency resolver simile a quello di ASP.NET MVC, che però per default non è configurato per sfruttare Ninject e quindi non è in grado di invocare il costruttore.
Dobbiamo quindi crearne uno personalizzato, che utilizzi questo container per risolvere la dipendenza da ICustomerRepository, e il modo più semplice è quello di creare una classe che erediti da DefaultDependencyResolver:
public class NinjectResolver : DefaultDependencyResolver { private IKernel _kernel; public NinjectResolver(IKernel kernel) { _kernel = kernel; } public override object GetService(Type serviceType) { var result = _kernel.TryGet(serviceType); if (result == null) return base.GetService(serviceType); return result; } public override IEnumerable<object> GetServices(Type serviceType) { var result = _kernel.GetAll(serviceType); return result.Union(base.GetServices(serviceType)); } }
L'idea di base è assolutamente simile al Dependency Resolver di ASP.NET MVC, ossia un oggetto che restituisca i componenti richiesti tramite i metodi GetService e GetServices. Andando nello specifico, l'implementazione che abbiamo realizzato sfrutta in prima istanza il kernel di Ninject per risolvere la dipendenza, sfruttando poi l'implementazione della classe base come fallback: è importante farlo perché comunque ASP.NET SignalR sfrutta questo resolver anche per costruire servizi interni di sistema, che non sono registrati su Ninject.
Per attivare questo resolver, è sufficiente specificarlo in fase di configurazione del routing:
public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); app.MapSignalR(new HubConfiguration() { Resolver = new NinjectResolver(NinjectWebCommon.Kernel) }); } }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Visualizzare le change sul plan di Terraform tramite le GitHub Actions
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Utilizzare Model as a Service su Microsoft Azure
Aggiungere interattività lato server in Blazor 8
Disabilitare automaticamente un workflow di GitHub
Limitare le richieste lato server con l'interactive routing di Blazor 8
Sfruttare MQTT in cloud e in edge con Azure Event Grid
Evitare il flickering dei componenti nel prerender di Blazor 8
Reactive form tipizzati con modellazione del FormBuilder in Angular
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione