2009-07-09 12 views
9

Sé que algunos marcos DI admiten esto (por ejemplo, Ninject), pero específicamente quiero saber si es posible con Autofac.¿Puede Autofac hacer autoaglomeración automática?

Quiero ser capaz de pedir un contenedor Autofac para una clase concreta, y obtener una instancia con todas las dependencias de constructor apropiadas inyectadas, sin registrar esa clase concreta. es decir, si no Ato de forma explícita, a continuación, de forma automática obligar a la clase concreta a sí mismo, como si hubiera llamado builder.Register<MyClass>();

Un buen ejemplo de cuando esto sería útil es ViewModels. En MVVM, la estratificación es tal que solo la vista depende del modelo de vista, y eso a través de la escritura suelta, y usted no prueba la vista de todas maneras. Por lo tanto, no es necesario burlarse de ViewModel para realizar pruebas, por lo que no hay razón para tener una interfaz para cada ViewModel. Entonces, en este caso, el patrón DI habitual de "registrar esta interfaz para resolver esta clase" es una complejidad innecesaria. Explícito autoaglutinante, como builder.Register<MyClass>();, también se siente como un paso innecesario cuando se trata de algo tan sencillo como una clase concreta.

Conozco el reflection-based registration example en los documentos de Autofac, pero eso no es para mi gusto tampoco. No quiero la complejidad (y lentitud) de registrar cada clase posible antes de tiempo; Quiero que el marco me dé lo que necesito cuando lo necesite. Convención sobre la configuración, y todo eso.

¿Hay alguna forma de configurar Autofac para que pueda decir "Oh, este es un tipo concreto, y nadie lo ha registrado todavía, así que simplemente actuaré como si hubiera sido registrado con la configuración predeterminada"?

Respuesta

12
builder.RegisterTypesMatching(type => type.IsClass) 

Si look at the source verá que RegisterTypesMatching (y RegisterTypesFromAssembly) no está haciendo ninguna reflexión. Todo lo que Autofac está haciendo en este caso es registrar una regla que acepte un tipo o no. En mi ejemplo anterior acepto cualquier tipo que sea una clase.

En el caso de RegisterTypesFromAssembly, Autofac registra una regla que dice "si el tipo que está tratando de resolver tiene Assembly == el ensamblado especificado, entonces le daré una instancia".

Así:

  1. ningún tipo de reflexión se realiza en tiempo de registro
  2. se resolverá cualquier tipo que coincide con los criterios

En comparación con registrar los tipos de hormigón directamente, esto será tener un golpe de perforación en tiempo de resolución ya que Autofac tendrá que resolver, por ejemplo requisitos del constructor Dicho eso, si vas con el ámbito de instancia predeterminado, que es singleton, solo tomas el hit la primera vez que resuelves ese tipo. La próxima vez usará la instancia de singleton ya creada.

Actualización: en Autofac 2 hay una manera mejor de que el contenedor pueda resolver cualquier cosa. Esto implica the AnyConcreteTypeNotAlreadyRegistered registration source.

+0

Sweet - suena exactamente como lo que estaba buscando. ¡Gracias! –

2

qué pasa:

builder.RegisterTypesFromAssembly(Assembly.GetExecutingAssembly()); 

se realiza ninguna reflexión, como Peter Lillevold points out.

+1

Ha eliminado mis comentarios anteriores porque tenía razón (como ha aclarado en su edición): RegisterTypesFromAssembly no refleja en masa como su nombre lo sugiere. Es solo uno de una familia de funciones abreviadas de RegisterTypesMatching, y hace exactamente lo que estoy buscando, pero con un control mucho más fino, que es bastante dulce. Mis disculpas por malinterpretar tu respuesta la primera vez. –

+0

El enlace que diste está roto ... – Guillaume

+1

por favor, perdónenme pero esta respuesta es de 3 años: P además, mucho ha sucedido con autofac desde entonces, no creo que nada de esto sea relevante por más tiempo ... –

Cuestiones relacionadas