2010-06-05 6 views
6

J'ai utilisé Unity pendant un certain temps mais je l'ai toujours utilisé avec l'injection de constructeur. Afin de réduire le nombre de classes que je dois injecter dans mes modèles de vue (comme mes commandes en dépendent), j'ai pensé que j'essaierais de créer un concept utilisant Property Injection et ainsi annuler les exigences pour les grandes listes de paramètres du constructeur. Voici le scénario ...Injection de propriété avec Unity provoquant un débordement de pile

Je crée un modèle de vue dont les commandes se trouvent dans les propriétés qui utilisent/mettent à jour le modèle de vue de l'arrosage d'une manière ou d'une autre. Je souhaite transmettre l'instance du modèle View dans les constructeurs des commandes situées dans les propriétés View Models. Par exemple.

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()); 

Quand je résous la classe MainViewModel je reçois une exception StackOverflow (si Visual Studio revient du tout). Maintenant, je m'attendrais à ce que Unity crée d'abord une instance de MainViewModel puis, comme il s'agit essentiellement d'un singleton, regarde l'instance du modèle View et crée la commande Pass dans le MainViewModel nouvellement créé, mais évidemment je me trompe.

Des idées?

Répondre

9

Il s'agit de l'erreur Circular References, et ceci, comme il est dit, c'est la responsabilité du développeur de l'éviter. Donc MainViewModel fait référence à LoadCustomersCommand qui est des références à MainViewModel -> StackOverflow.

La seule que vous pouvez faire est

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

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

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

et résoudre vous devrez effectuer les opérations suivantes

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

Merci pour la réponse et votre lien. Je pensais que c'était le cas mais en raison de l'injection de propriété, je pensais que le MainViewModel aurait été dans le conteneur au moment où la classe de propriétés est instanciée et la référence 'circulaire' ne serait pas un problème - mais évidemment pas. Merci d'avoir nettoyé ça! – Adam

Questions connexes