unity mvc injection framework example dependency control dependencies inversion-of-control asmx code-injection

dependencies - mvc - Inyección de dependencia ASMX e IoC



inversion of control c# (2)

Desafortunadamente, no hay ninguna manera de realizar una inyección de constructor con servicios web en ASP.NET. Es un requisito de ASP.NET que proporcione un constructor predeterminado. El constructor de MyService es lo más cercano a la raíz de la composición que puede obtener con este tipo de servicio web, sin utilizar un contenedor DI.

Con ASP.NET no es inusual tener múltiples raíces de composición. Que pueden ser los constructores de los servicios web individuales y páginas web. Si está utilizando ASP.NET MVC, es el ControllerFactory, que es más fácil de usar para el usuario.

Con su implementación, la parte importante no es mover la construcción del gráfico de objetos desde el servicio web, ya que esta es la raíz de su composición. Lo principal que debe hacer es mantener el servicio web lo más delgado posible, mantener la mayor parte de la lógica en la dependencia para que se pueda probar o reutilizar. Extraer información de los encabezados HTTP es un ejemplo de una tarea que el servicio web podría luego transferir esa información a la dependencia.

Un buen libro para referirse a los patrones y técnicas de DI es la inyección de dependencia en .NET por Mark Seemann.

Si su servicio web implementó System.Web.IHttpHandler lugar de derivar de System.Web.Services.WebService , podría implementar su DI como:

Global.ashx.cs

public class Global : HttpApplication { protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; var needsMyBusinessService = context.Handler as INeedMyBusinessService; if (needsMyBusinessService != null) needsMyBusinessService.MyBusinessService = new MyBusinessService(); } }

MyService.ashx.cs

public class MyService : IHttpHandler, INeedMyBusinessService { public IMyBusinessService MyBusinessService { get; set; } public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { // uses my dependency } }

INeedMyBusinessService.cs

public interface INeedMyBusinessService { IMyBusinessService MyBusinessService { get; set; } }

Sin embargo, el problema con esta implementación es que no funciona con los servicios web que implementan System.Web.Services.WebService ya que el objeto de servicio web no se inicializa hasta después de que se llame el evento PreRequestHandlerExecute , que es el último evento antes de que se ProcessRequest .

El ejemplo anterior funciona si desea tener una instancia única para cada servicio web. Si quisiera tener la misma instancia (ciclo de vida de Singleton) de MyBusinessService para cada solicitud de servicio web, podría implementar el archivo Global.ashx.cs así:

public class Global : HttpApplication { private static IMyBusinessService businessService; protected void Application_Start(object sender, EventArgs e) { Global.businessService = new MyBusinessService(); } protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; var needsMyBusinessService = context.Handler as INeedMyBusinessService; if (needsMyBusinessService != null) needsMyBusinessService.MyBusinessService = Global.businessService; } }

Así que me quedé atascado al intentar que mi servicio web asmx usara la inyección de dependencia y usara un IoC para hacerlo. Quiero que mi servicio web pueda usar mis servicios internos de la capa empresarial. El servicio web debe ser utilizado por un cliente externo de un dominio diferente y se utilizará principalmente para enviar y recibir información sobre entidades como Pedidos y Clientes.

Un ejemplo sería:

public class MyService : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return new MyBusinessService().MyMethod(); } } public class MyBusinessService : IMyBusinessService { public string MyMethod() { return "hello"; } }

Quiero usar la inyección de dependencia para eliminar la necesidad de "renovar" mi servicio, pero no puedo encontrar la manera de hacerlo. Puedo hacer que funcione con la DI de los pobres, o al menos creo que se llama "pobre".

Me gusta esto:

public class MyService : System.Web.Services.WebService { private IMyBusinessService _myService; public MyService(IMyBusinessService myService) { _myService = myService; } public MyService() : this(new MyBusinessServie()) { } [WebMethod] public string HelloWorld() { return _myService.MyMethod(); } }

Pero simplemente no puedo entender cómo usar un contenedor IoC para inyectar mis dependencias porque no puedo hacer que el servicio se ejecute sin un constructor sin parámetros. Por favor, sea amable, no soy un programador experimentado y acabo de comenzar a probar la inyección de dependencias y conseguí que funcionara bien en la aplicación de formularios de Windows con structuremap, pero me quedé atascado en esta.


Solo puede tener un constructor sin parámetros en un servicio web. Sin embargo, lo que podría hacer es tener una propiedad en la clase WebService y, dentro del constructor sin parámetros, llamar a algo como _myDependency = container.resolve ();