Respuesta

14

Como se describe here, la API web utiliza una resolución de dependencias.

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.GetInstances(serviceType); 
    } 

    public void Dispose() 
    { 
    } 
} 

Y en sus Global.asax.cs, incluya esta línea para registrar el solucionador de dependencias:

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(); 

Aparte de eso, la nueva API Web es muy fácil de usar con contenedores COI.

No he investigado todavía, pero creo que el método BeginScope que dejé en blanco se puede usar con contenedores secundarios.

Editar:

La implementación anterior funciona muy bien; de hecho, prefiero la alternativa que estoy a punto de contarte. Éste resolverá cualquier tipo según las mejores capacidades de StructureMap y emitirá errores cada vez que algo vaya mal. Me gusta ver errores porque me muestran lo que hice mal.

Sin embargo, la API espera que GetService devuelva nulo si algo sale mal. Así que sea compatible con la API, esta es la aplicación recomendada:

public object GetService(Type serviceType) 
{ 
    if (serviceType.IsAbstract || serviceType.IsInterface) 
     return ObjectFactory.TryGetInstance(serviceType); 
    else 
     return ObjectFactory.GetInstance(serviceType); 
} 

La diferencia es que sólo se ve TryGetInstance para este tipo registrados en el contenedor y devolverá un valor nulo si algo va mal. serviceType.IsAbstract || serviceType.IsInterface se considera lo suficientemente bueno como un control para decidir qué método usar. Mi respuesta original fue simple y directa, pero @PHeiberg señala en los comentarios que no fue del todo "correcta". Ahora que tiene conocimiento, use lo que le parezca mejor.

+0

StructureMap no maneja la dependencia resolución como se esperaba aquí. Mira este ejemplo y los comentarios de Jeremy: http://ardalis.com/How-Do-I-Use-StructureMap-with-ASP.NET-MVC-3 – PHeiberg

+0

En realidad, esto funcionará. Jeremy dice que 'TryGetInstance' solo se resuelve si' serviceType' está explícitamente registrado. 'GetInstance' todavía resolverá los tipos que no están registrados pero son concretos. – kelloti

+0

La resolución de instancias funcionará con su código. Sin embargo, interpreto el enlace que publiqué como la "Mejor práctica" propuesta, ya que Jeremy mismo [lo recomienda] (http://codebetter.com/jeremymiller/2011/01/23/if-you-are-using-structuremap-with -mvc3-por-leer-esto /). Supongo que se supone que el método GetService devolverá nulo, en lugar de generar una excepción si el contenedor no puede resolver el tipo. – PHeiberg

8

La versión de versión de la API web de ASP.NET utiliza el resolutor de dependencias (implementación de la interfaz IDependencyResolver) e introduce también un nuevo concepto - ámbito de dependencia (implementación de la interfaz IDependencyScope). Es importante implementar IDependencyScope correctamente: si se implementa correctamente, permite liberar recursos (creados en el alcance) cuando se elimina IDependencyScope. Y está dispuesto cuando finaliza la solicitud.

IDependencyScope funciona mejor cuando el contenedor admite contenedores anidados (o secundarios). StructureMap lo hace desde la versión 2.6.1.

escribí un artículo cómo configurar StructureMap en Web API: Configuring StructureMap in ASP.NET WebAPI

También se puede consultar el artículo de Mike Wasson: Using the Web API Dependency Resolver