asp.net dependency-injection asp.net-web-api structuremap

Configurar la inyección de dependencias con ASP.NET Web API 2.1



dependency-injection asp.net-web-api (2)

Me gustaría darte una sugerencia y una explicación sobre por qué no seguir así y cómo hacerlo de manera diferente (incluso diría que es mejor y más adecuado).

La explicación completa y completa del diseño inadecuado de IDependencyResolver se puede encontrar aquí: Inyección de Dependencia y Administración de por vida con ASP.NET Web API por Mark Seemann

Permítanme citar estas partes esenciales:

El problema con IDependencyResolver

El principal problema con IDependencyResolver es que es esencialmente un localizador de servicios . Hay muchos problemas con el anti-patrón del localizador de servicios , pero la mayoría de ellos ya los he descrito en otro lugar de este blog (y en mi libro). Una desventaja del Localizador de servicios sobre el que aún no he escrito tanto es que dentro de cada llamada a GetService no hay ningún contexto. Este es un problema general con el anti-patrón del localizador de servicios, no solo con IDependencyResolver.

Y también:

... el gráfico de dependencia necesita saber algo sobre el contexto. ¿Cuál fue la URL de solicitud? ¿Cuál fue la dirección base (nombre de host, etc.) solicitada? ¿Cómo puede compartir instancias de dependencia dentro de una única solicitud? Para responder a estas preguntas, debe conocer el contexto e IDependencyResolver no proporciona esta información.

En resumen, IDependencyResolver no es el gancho correcto para componer gráficos de dependencia. ** Afortunadamente, ASP.NET Web API tiene un mejor punto de extensibilidad para este propósito. **

ServiceActivator

Entonces, la respuesta en este escenario sería el ServiceActivator . Por favor, eche un vistazo a esta respuesta:

Un ejemplo de ServiceActivator :

public class ServiceActivator : IHttpControllerActivator { public ServiceActivator(HttpConfiguration configuration) {} public IHttpController Create(HttpRequestMessage request , HttpControllerDescriptor controllerDescriptor, Type controllerType) { var controller = ObjectFactory.GetInstance(controllerType) as IHttpController; return controller; } }

Todo lo que podemos hacer con StructureMap, está en su lugar. Las características clave del marco de API web todavía están en su lugar ... no tenemos que hackearlas. Y también estamos usando DI / IoC entonces Service locator

Estoy creando un sitio ASP.NET Web API 2.1 y como quiero inyectar dependencias directamente en los controladores, he creado mi propia implementación de IDependencyResolver para que StructureMap lo haga por mí.

public class StructureMapDependencyResolver : IDependencyResolver { public IDependencyScope BeginScope() { return this; } public object GetService(Type serviceType) { return ObjectFactory.GetInstance(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return ObjectFactory.GetAllInstances(serviceType).Cast<object>(); } public void Dispose() { } }

Luego le dije a la API web que use esta clase al agregar esta línea al método Application_Start en Global.asax

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();

Eso compilado, pero cuando intenté acceder a cualquiera de los métodos de API en un navegador, recibí un error como este

No Default Instance defined for PluginFamily System.Web.Http.Hosting.IHostBufferPolicySelector, System.Web.Http

Esa fue relativamente fácil de resolver ya que agregué una línea a mi configuración de StructureMap

this.For<IHostBufferPolicySelector>().Use<WebHostBufferPolicySelector>();

Sin embargo, luego obtuve otros errores similares para otras clases de System.Web.Http y si bien pude resolver algunos de ellos, estoy atascado en cómo tratar con 3 de ellos, concretamente ITraceManager, IExceptionHandler e IContentNegotiator.

El problema es que TraceManager, que parece ser la implementación predeterminada de ITraceManager, es una clase interna y, por lo tanto, no puedo hacer referencia a ella en mi configuración de StructureMap.

Entonces, ¿estoy yendo por este camino completamente equivocado o hay alguna otra forma de inyectar estas clases internas?


Simplemente intente usar UnityHierarchicalDependencyResolver en lugar del otro. Funcionó para mí Esto es para referencia futura si alguien quisiera usar Unity