2010-06-10 12 views
6

En un nuevo proyecto WPF (VS2010) estoy usando Unity 2 por primera vez. En este proyecto yo uso la siguiente estructura:Cómo resolver con Unity en una solución multiproyecto

Solución

proyecto WPF

Clase Biblioteca1

Clase Biblioteca2 Biblioteca

Clase 3 ....

Registro de la Se realizan diferentes tipos utilizando Unity en Proyecto WPF utilizando el siguiente fragmento:

IUnityContainer container = new UnityContainer() 
          .RegisterType<IObjectContext, ObjectContextAdapter>() 
          .RegisterType<IConnectionStringProvider, ConnectionStringProvider>() 
          .RegisterType(typeof(IRepository<>), typeof(Repository<>)); 

Digamos ahora que me gustaría obtener el Repositorio <Orders> inyectado constructor resuelto en clase Biblioteca1. ¡Al parecer, el contenedor no se conoce en los otros proyectos!

¿Cómo haré eso?

Respuesta

9

Principalmente estoy de acuerdo con la respuesta de Chris, pero creo que los archivos de configuración son asquerosos (especialmente para Unity) así que aquí hay una solución que le permitirá usar la configuración de tiempo de ejecución sin referencias circulares. Vamos a hacer esto con los registros.

Cree un proyecto de infraestructura que contendrá IConfigureUnity.

public interface IConfigureUnity 
{ 
    public void Configure(UnityContainer container); 
} 

Cada uno de los proyectos de la biblioteca de su clase será responsable de implementar esta interfaz para registrar sus propias clases.

public class RegistryForSomeClassLibrary : IConfigureUnity 
{ 
    public void Configure(UnityContainer container) 
    { 
     container 
      .RegisterType<IObjectContext, ObjectContextAdapter>() 
      .RegisterType<IConnectionStringProvider, ConnectionStringProvider>() 
      .RegisterType(typeof(IRepository<>), typeof(Repository<>)); 
    } 
} 

Luego en su proyecto WPF necesitará crear el contenedor y aplicar estos registros.

var container = new UnityContainer(); 
new RegistryForSomeClassLibrary().Configure(container); 
new RegistryForAnotherClassLibrary().Configure(container); 

Ahora tiene una instancia de contenedor completamente configurada sin ningún archivo de configuración.

+0

Digamos que tengo un cuadro de diálogo en Class Library 1 llamado "ManageUser". ¿Cómo obtiene ManageUser la instancia del contenedor declarado en el proyecto WPF? –

+1

@Ryan - ¿Hay alguna razón para usar una interfaz en un proyecto común? ¿Por qué no hacer que la clase Registry y el método Configure sean estáticos y llamarlo así: 'RegistryForSomeClassLibrary.Configure (container); RegistryForAnotherClassLibrary.Configure (contenedor); 'He probado esto y funciona. ¿Me estoy perdiendo de algo? – Shevek

+0

@Shevek, eso funciona bien. Solía ​​resolver mis registros utilizando la reflexión, pero me rendí en eso hace un tiempo. Ahora llamo explícitamente a 'Configure()' en cada registro. – Ryan

0

Para que varios proyectos utilicen el mismo UnityContainer en este escenario, necesita un proyecto "común" que contenga su UnityContainer y lo exponga de forma que todos los demás proyectos puedan acceder a él.

es decir

proyecto WPF

biblioteca de clases 1

biblioteca de clases 2

biblioteca de clases de 3

hits (UnityContainer vive aquí)

Para evitar circular dependencias del proyecto , Recomendaría usar Unity design-time configuration via a configuration file en lugar de la configuración en tiempo de ejecución (como lo ha hecho en su ejemplo). De lo contrario, su Biblioteca común tendrá que hacer referencia a los proyectos que contienen todos los tipos que resuelve y esos proyectos, a su vez, dependerán de la Biblioteca común (ya que es probable que exista la instancia de UnityContainer). Es posible que pueda hacer que funcione con la configuración en tiempo de ejecución, pero no lo he intentado; Sé que la configuración del tiempo de diseño funciona, ya que he hecho algunos proyectos usando un modelo exactamente como este.

+0

Gracias Chris, ¡intentalo! –

Cuestiones relacionadas