2010-07-27 7 views
2

Arrière-plan:
J'ai un contrôle utilisateur personnalisé basé sur un TreeView WPF. J'utilise le modèle MVVM et ont un modèle vue de base TreeNode classe et plusieurs modèles de vue dérivés tels que LocationNode, LocationFolder, PersonNode, PersonFolder, CollectionNode, CollectionFolder, etc..Gestion des transactions et des exceptions de base de données dans TreeView avec MVVM multi-niveaux

Un exemple de la façon dont pourrait être jeté l'arbre out:


- CollectionFolder 
--> CollectionNode 
    --> LocationFolder 
     -->LocationNode 
     -->LocationNode 
    --> PersonFolder 
     -->PersonNode 
--> CollectionNode 
--> CollectionNode 
+ CollectionFolder 
+ CollectionFolder 

Quand je joue glisser et déposer des opérations, chaque classe gère la logique métier, à savoir si je laisse tomber sur un sur un CollectionNode, le modèle de vue CollectionNode contient la logique comment ajouter le PersonNode son enfant PersonFolder.

Problème:
Tout fonctionne très bien, je peux glisser-déposer dans tous les sens, et le code est bien contenu dans les classes dervied. Si j'ai besoin d'ajouter une règle de dépôt supplémentaire, je l'ajoute au modèle de vue de cible de dépôt approprié.

Le problème est quand un PersonNode est ajouté à un PersonFolder je dois créer une nouvelle entrée de base de données pour refléter le fait que le modèle Person sous-jacente est maintenant aussi dans une nouvelle Collection. À l'heure actuelle, chaque modèle de vue dans l'arborescence a accès à la session/transaction de base de données en cours et peut effectuer l'insertion/la sauvegarde. Mais cela rend les exceptions et les erreurs extrêmement répétitives, mon code de gestion des exceptions est en cours de duplication sur tous les modèles de vue. Existe-t-il un meilleur moyen pour MVVM de gérer les interactions de mes bases de données?

Un extrait de code de mon événement Drop dans mon PersonFolder


// Create a new view model for the Person and add it to my children 
_children.Add(new PersonNode(droppedPerson)); 

// Create a new entry in the collection for this person 
CollectionEntry entry = new CollectionEntry(); 
entry.Entity = droppedPerson; 
entry.Collection = _collection; 

// Save the new entry 
using(var transaction = _uow.BeginTransaction(IsolationLevel.Serializable)) 
{ 
    // Add the entry to the session 
    _uow.Add(entry); 

    // Save the session 
    _uow.SaveChanges(); // [1] 

    // Commit transaction 
    transaction.Commit(); // [2] 
} 

[1] et [2] ont la possibilité de lancer des exceptions et doivent être manipulés dans des déclarations try/catch. Cependant, je ne veux pas dupliquer toute ma gestion des exceptions dans tous mes modèles de vue, des suggestions?

Je suppose que je pourrais toujours implémenter un singleton pour contenir la gestion de session et d'exception et passer mes nouvelles entités dans cela?

Répondre

1

Je suppose que la partie variable de votre dernier bloc de code est:

_uow.Add(entry); 

... donc, dans certains cas, vous pourriez effectivement vouloir beaucoup plus ou moins des actions pour arriver à cet endroit.

Je pense que c'est un bon candidat pour le "Hole in the Middle Pattern".

passer Fondamentalement juste un

Action<T> 

à un autre endroit (Singleton, peu importe) qui ouvre une transaction, passe le contexte (_uow) à votre action, et engage la transaction, et gère toutes vos exception logique. Votre code ressemblerait à:


// Create a new view model for the Person and add it to my children 
_children.Add(new PersonNode(droppedPerson)); 

// Create a new entry in the collection for this person 
CollectionEntry entry = new CollectionEntry(); 
entry.Entity = droppedPerson; 
entry.Collection = _collection; 

someSingleton.Execute(o => o.Add(entry)); 

Questions connexes