2011-07-06 13 views
20

Estoy trabajando en una aplicación ASP MVC 3 y estoy escribiendo un helper html personalizado. No es nada especial o enormemente complejo, pero necesitará una instancia de una interfaz desde el mapa de la estructura. Sé que puedo simplemente llamar a la fábrica de objetos de structuremaps desde el método, pero como el resto de la aplicación usa IoC en lugar de la ubicación del servicio, me gustaría mantenerlo así.Uso de IoC en los métodos de extensión

¿Hay alguna manera de insertar interfaces en los métodos de extensión desde dentro y la aplicación asp net mvc?

ACTUALIZACIÓN

Un ejemplo de lo que estoy haciendo podría ayudar:

public static class ShowUrl 
{ 
    public static string ForShow(this UrlHelper url, int showId) 
    { 
     var service = ObjectFactory.GetInstance<IPerformanceService>(); 

     var showName = service.GetPerformanceTitle(showId); 

     return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl())); 
    } 
} 

que se utiliza como esto:

<a href='<%= Url.ForShow(1)%>'> 

Esencialmente estoy tratando de construir una URL con una babosa de un ID de entidad. Tal vez estoy hablando de esto de una manera realmente tonta.

+0

¿Está utilizando el MVC DependencyResolver? – mccow002

Respuesta

6

No hay forma de inyectar dependencias en un método de extensión.

Para los asistentes ASP.NET MVC, vas a tener que hacer una especie de servicio de ubicación, ya sea que lo entierres con algún tipo de abstracción depende de ti.

+3

Puede inyectar dependencias en un método de extensión, simplemente pasando las dependencias en como argumento de método (método de inyección). Sin embargo, no es realmente conveniente, especialmente cuando necesita pasar múltiples dependencias. – Steven

+1

Buen punto. Originalmente había incluido un código de demostración para mostrar exactamente eso, pero me di cuenta de que el resultado final no era más bonito. –

21

No recomendaría hacer esto. Los métodos de extensión generalmente se usan mejor para operaciones simples y conocidas directamente en un tipo. Si su método de extensión depende de tener una instancia de otro tipo, es probable que no sea un método de extensión para comenzar.

Considere hacer una clase de servicio real que realice esta funcionalidad e inyectándola donde se necesite. Si realmente necesita esto en un método de extensión, considere incluir la funcionalidad que requiere su método de extensión en otra clase/método estático y evite el uso de cualquier tipo de inyección o ubicación.

Compartir algún código puede arrojar más luz sobre su situación específica.

6

NO debe llamar a structuremap directamente en su método de extensión. También, se debe crear una versión contrastable que toma un argumento IPerformanceService, como a continuación:

public static class ShowUrl 
{ 
    public static string ForShow(this UrlHelper url, int showId) 
    { 
     //Use the MVC DependencyResolver NOT Structuremap directly (DependencyResolver is using structuremap) 
     return url.ForShow(showId, DependencyResolver.Current.GetService<IPerformanceService>()) 
    } 

    //For Unit Testing 
    public static string ForShow(this UrlHelper url, int showId, IPerformanceService performanceService) 
    { 
     var showName = performanceService.GetPerformanceTitle(showId); 
     return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl())); 
    } 
} 

Ahora se puede pasar en una aplicación concreta de IPerformanceService en el método de prueba de la unidad.

Assert.Equal("TheUrl", url.ForShow(8, new PerformanceService()); 

Más información sobre burlarse UrlHelper: ASP.NET MVC: Unit testing controllers that use UrlHelper

Cuestiones relacionadas