2009-07-20 20 views
12

Tengo un UserControl de WPF en el que me gustaría insertar dependencias. ¿Cuál es la mejor manera de hacerlo con Ninject?Inyección de dependencias en WPF usando Ninject

Para tomar un ejemplo concreto: tengo un UserControl llamado MapView, y quiero inyectar una instancia de mi IDialogueService en él, mediante la inyección de propiedad o del constructor. Actualmente, no estoy usando cualquier inyección de dependencias, y mi control se crea en XAML:

<Window x:Class="GameWindow" ...> 
    <Grid Name="root"> 
     <MapView x:Name="mapView" ... /> 
     <!-- other stuff here --> 
    </Grid> 
</Window> 

Creación de un iKernel, y la unión del IDialogueService, es bastante sencillo. Pero estoy atascado en cómo usar el kernel para inyectar dependencias en mi MapView. Todavía soy un novato total en Ninject, así que tal vez haya algo obvio que me estoy perdiendo.

me ocurren varias maneras de resolver esto:

  1. una instancia del MapView en el código. Retire la <MapView ... /> desde el XAML, y en lugar de añadir este al constructor de GameWindow:

    public GameWindow(IKernel kernel) { 
        root.Children.Add(kernel.Get<MapView>()); 
    } 
    

    Desventajas: la complejidad adicional de no usar XAML; GameWindow tiene una dependencia en IKernel.

  2. Mantener la creación de instancias en XAML, y el uso de la inyección de la propiedad en su lugar:

    public GameWindow(IKernel kernel) { 
        kernel.Inject(mapView); 
    } 
    

    Desventaja: docs ninject dicen que inyectan() "no debe ser utilizado para la mayoría de los casos", por lo que ni siquiera saben si hace lo que creo que hace, o si tiene sentido usarlo aquí. Y GameWindow todavía tiene una dependencia en IKernel.

  3. Agregue parámetros/propiedades inyectables a GameWindow que pase los valores a lo largo de MapView (probablemente a través de las propiedades en MapView), y luego use Get<GameWindow>(). Desventaja: ahora paso manualmente dependencias por todas partes, que es lo que se supone que un marco de DI debe automatizar para mí.

  4. Después de instanciar el GameWindow, recorra el árbol lógico y llame a IKernel.Inject() en todo. Desventajas: nuevamente, no sé si Inject() hace lo que creo que es, o si es apropiado aquí. La persona que llama debe recordar hacer lo de caminar-el-árbol-visual-e-inyectar después de crear una instancia de GameWindow.

¿Hay una manera mejor de hacer esto? Tal vez una extensión WPF para Ninject que me permite hacer un Get<GameWindow>(), y camina automáticamente el árbol lógico para mí (como en el n. ° 4), haciendo inyección de propiedad en todo. Si tal cosa no existe, ¿sería posible para mí escribirla?

¿Cómo se acercan a usar Ninject con WPF? ¿Utiliza alguno de los enfoques anteriores (y si es así, puede compartir arriba/abajo no sé)? ¿Tienes mejores enfoques?

Respuesta

4

1) es el mejor. También encontrará que es un punto de entrada conveniente para las funciones de Mapview.

Además, en lugar de pasar el kernel, simplemente haz kernel.Obtén < GameWindow>() y [inyecta] MapView en GameWindow.

+0

Inyectar el control nunca se me ocurrió, pero ahora parece obvio. ¡Gracias! –

Cuestiones relacionadas