2010-06-05 11 views
6

He estado usando Unity durante bastante tiempo, pero siempre lo he usado con la inyección de constructor. En un esfuerzo por reducir el número de clases que tengo que inyectar en mis modelos de visualización (ya que mis comandos dependen de ellos) pensé que intentaría crear un concepto que utilizara Property Injection y así anular el requisito para las listas de parámetros de constructores grandes. Aquí está el escenario ...Inyección de propiedad con Unity que causa el desbordamiento de la pila

Estoy creando un modelo de vista que tiene comandos ubicados en propiedades que usan/actualizan el modelo de vista de mangueras de alguna manera. Deseo pasar la instancia del Modelo de Vista a los constructores de los Comandos ubicados en las propiedades de Ver Modelos. P.ej.

public MainViewModel 
{ 
    public MainViewModel() 
    { 
     Customers = new ObservableCollection<CustomerViewModel>(); 
    }   

    [Depedency("LoadCommand")] 
    public ICommand LoadCustomersCommand { get; set; } 

    public ObservableCollection<CustomerViewModel> Customers { get; private set; } 
} 

public LoadCustomersCommand : ICommand 
{ 
    public LoadCustomersCommand(MainViewModel mainViewModel) 
    { 
     //Store view model for later use 
    } 

    //... implementation 
} 

//Setup code in App.Xaml 

IUnityContainer unityContainer = new UnityContainer(); 
unityContainer.RegisterType<ICommand, LoadCommand>("LoadCommand"); 
unityContainer.RegisterType<MainViewModel>(new ContainerControlledLifetimeManager()); 

Cuando resuelvo la clase MainViewModel recibo una excepción stackoverflow (si Visual Studio vuelve en absoluto). Ahora esperaría que Unity creara una instancia de MainViewModel primero, ya que básicamente es un singleton, luego mire la instancia del View Model y cree el Command passing en el recién creado MainViewModel, pero obviamente estoy equivocado.

¿Alguna idea?

Respuesta

9

Esto es Circular References error, y esto como se dijo, esta es la responsabilidad del desarrollador para evitarlo. Así que MainViewModel hace referencia a LoadCustomersCommand que es una referencia a MainViewModel -> StackOverflow.

Así que el único que puede hacer es

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     Customers = new ObservableCollection<CustomerViewModel>(); 
    }   

    //no dependency. 
    public ICommand LoadCustomersCommand { get; set; } 

    public ObservableCollection<CustomerViewModel> Customers { get; private set; } 
} 

y para resolver, se tendrá que hacer las siguientes

var mainModel = unityContainer.Resolve<MainViewModel>(); 
mainModel.LoadCustomersCommand =  unityContainer.Resolve<ICommand>("LoadCommand"); 
+0

Gracias por la respuesta y su enlace. Pensé que ese podría ser el caso, pero debido a la inyección de propiedad, pensé que MainViewModel estaría en el contenedor en el momento en que se crea una instancia de la clase de propiedades y que la referencia 'circular' no sería un problema, pero obviamente no. Gracias por limpiar eso! – Adam

Cuestiones relacionadas