2011-04-25 11 views
15

Estoy usando Autofac con integración ASP.NET MVC, todos mis controladores reciben dependencias y Autofac resuelve automáticamente las dependencias anidadas. Funciona bienAcceso global a la resolución de dependencias autofac en ASP.NET MVC3?

Pero, ¿cómo puedo resolver una dependencia fuera del alcance de la creación de instancias del controlador? En algunos lugares, en lo profundo de mi código, necesito preguntarle al solucionador por mi registrador. Por un lado, parece incorrecto pasar el registrador como una dependencia a cada pequeño objeto que creo, y por otro parece incorrecto depender del resolvedor de dependencias tan profundo en mi código

Por ejemplo, tengo una clase llamada Resultado que se devuelve de muchas acciones. Es un objeto usado consistente en el que mi código de aplicación puede confiar para volver desde las capas más profundas. Cuando el código en capas más profundo agrega un error de UI a este objeto, quiero agregarlo automáticamente al registrador, que debe resolverse. Tener todas las clases tomar una dependencia de registrador acaba de ponerse en el camino

Cualquier ayuda apreciada gracias

Respuesta

7

Bien puede utilizar concurso completo (pub/enfoque sub) si la dependencia en cada objeto que irrita pero yo no lo hay cualquier cosa incorrecta con la dependencia en el solucionador Logger central. Si realmente necesita iniciar sesión en cada clase, puede acercarse al registro como un aspecto central de su aplicación y lo aborda mentalmente como otros tipos comunes de bibliotecas como String o Ints que son ubicuos y de los que puede confiar. Pero te sugiero algo más. En mi humilde opinión, debe revisar la arquitectura y no iniciar sesión en todas las clases. Si su registro es solo (o principalmente) sobre la escritura de los errores (excepciones), entonces no contamine su modelo de dominio con él. Vamos a colocarlo en la capa de servicio insteád. Este tipo de capa de orquestación puede evaluar correctamente cada excepción atrapada y registrar solo lo que sea necesario. Hagamos burbujas en esas excepciones en el lugar más bajo posible en la traza de pila y las manejemos como la última cosa.

+2

Tienes razón. Parecía un lugar tan natural para poner el registro, pero solo estoy agregando responsabilidades adicionales a las clases. Ahora agrego errores ui a ActivityLog en BaseController.OnActionExecuted(). Primero del diccionario ModelState.En segundo lugar, ahora tengo un único objeto Result en BaseController que todas las acciones usan cuando llaman a los métodos de dominio/repos. En OnActionExecuted() nuevamente, agrego estos errores a mi ActivityLog. Entonces, todo está centralizado, pero las cosas están en el lugar correcto. Gracias por alejarme de una mala solución. Esto es mucho mejor y permite que todo sea comprobable –

+0

Solo para agregarlo, me he decidido por una solución: mi capa de servicio devuelve un objeto Result que encapsula cualquier excepción, y ya ha degradado las excepciones de entrada del usuario a solo mensajes de error listos para ser mostrado en el ui. El objeto Result está en mi controlador base para todos los controladores, y las comprobaciones de OnActionExecuted del controlador base Result.Exceptions, este es el único lugar donde registro excepciones y es solo un simple bucle y un trazador de líneas para registrar cada excepción. Las excepciones que ocurren en los controladores las maneja la OnException del controlador base –

35

Lo que estás buscando es de DependencyResolver.Current MVC:

var logger = DependencyResolver.Current.GetService<ILogger>(); 
0

Las personas que buscan otra solución a este problema podría echar un vistazo a este otro SO answer que se aprovecha de IComponentContext servicio de resolución se inyecta directamente por Autofac.

3

El uso de DependencyResolver.Current es definitivamente una manera de resolver su problema en ASP .NET MVC, dado que es una característica de marco. Sin embargo, me gustaría en primer lugar tratar de seguir la siguiente recomendación de la "Best Practices" section of the Autofac Wiki

"Acceso de componentes al contenedor, almacenándolo en una propiedad estática pública, o haciendo funciones como Resolve() disponible en una clase global 'del COI El diseño de este servicio tiene más en común con el patrón de Localizador de servicios. Si los componentes tienen una dependencia en el contenedor, observe cómo están usando el contenedor para recuperar los servicios y agregue esos servicios al componente. (Injección inyectada) argumentos del constructor en su lugar. Utilice los tipos de relación para los componentes que necesitan instanciar otros componentes o interactuar con el contenedor de formas más avanzadas. "

Solo si no es posible volver a establecer una dependencia como se sugirió anteriormente, ¿usaría DependencyResolver?

+0

La documentación de mejores prácticas de Autofac está ahora en http://autofac.readthedocs.io/en/latest/best-practices/index.html –

Cuestiones relacionadas