2009-05-11 6 views
4

Je viens de refacturer une nouvelle classe de domaine à partir d'une classe de présentateur, mais je n'arrive pas à déterminer où l'instancier.Où dois-je placer la création de dépendances pour une classe Presenter dans une architecture Passive View?

Cela fait partie d'un effort de refactoring plus important avec un projet hérité mal entretenu.

Le présentateur est en cours de création par l'événement OnLoad de la vue et la vue est transmise en tant que paramètre dans le constructeur. Toutes les méthodes publiques dans le présentateur sont sans paramètre et retournent le vide. Ils communiquent avec la vue en utilisant les propriétés publiques de la vue. La vue, étant essentiellement une forme humble dépend entièrement du présentateur pour tout.

Ceci est le modèle de vue passive typique et je voudrais continuer à y adhérer. Ce qui m'amène à mon dilemme. J'ai besoin de créer une instance de mon nouvel objet de domaine pour le présentateur à utiliser. Si je le passe à travers le constructeur, alors la vue doit le créer et obtenir une dépendance non nécessaire.

  • Si je le crée n'importe où dans le présentateur, je ne peux pas le remplacer par un objet simulé dans mes tests unitaires. Si j'en fais une propriété publique du présentateur, j'introduis une dépendance de l'ordre de création sur les méthodes du présentateur où il est utilisé et je n'ai toujours pas résolu quelle classe externe est responsable de sa création. Je n'emploie actuellement aucun cadre d'injection de dépendance. Bien que je sois intéressé à en utiliser un dans le futur, le code source est encore trop fragile pour introduire un framework tiers dans le mix.

    Je suis ouvert à toutes suggestions.

  • Répondre

    1

    J'ai trouvé une solution beaucoup plus simple. Voici un exemple de ma classe d'origine:

    public Presenter(IView view) 
    { 
        this.View = view; 
    } 
    

    Je voulais passer ma nouvelle dépendance comme argument du constructeur, mais ne voulait pas ajouter cette dépendance à mon avis aussi. Constructeur enchaînant à la rescousse!

    public Presenter(IView view):this(view, new Dependency()){} 
    
    public Presenter(IView view, IDependency dependency) 
    { 
        this.View = view; 
        this.Dependency = dependency; 
    } 
    

    Maintenant, le code de production continue d'utiliser l'interface d'origine alors que les tests unitaires utilisent le nouveau passage dans simulacres à la fois la vue et la dépendance. Si le nombre de dépendances continue de croître, un refactoring sera nécessaire mais pour l'avenir immédiat, c'est une solution idéale.

    2

    Je l'ai déjà fait !!! Regardez ici my repository. Mon choix ici est d'utiliser le constructeur ... satisfaisant le plus gourmand Je suis sûr que le présentateur est en haut. Dans votre cas, vous pouvez fournir à partir de vue spécifique impl pour les dépendances.

    have fun :)

    +0

    Votre motif est intéressant. Votre vue correspond au mode de vue passif, mais je ne l'ai jamais vu avec un présentateur et un contrôleur.Les exemples que j'ai vus ont le présentateur en train de soulever des objets lourds et de parler aux objets du domaine et à un magasin de données. Tandis que le tien a un présentateur comme un intermédiaire et le contrôleur faisant le travail. Quel est l'avantage de la couche supplémentaire? –

    +0

    L'avantage est évident ... tout le travail lourd est fait présentateur la responsabilité du contrôleur est de gérer la navigation dans des scénarios complexes. Ici est réalisé la navigation découplée, par exemple pour les assistants où les vues ne connaissent pas les autres ... tout est géré par le contrôleur. – ruslander

    0

    Je vais pour un dépôt ou une usine pour l'instant. Ce serait testable immédiatement. À l'avenir, vous pouvez remplacer son implémentation pour aller à une bibliothèque de DI.

    public class DomainObjectsRepository 
    { 
        /// <summary> 
        /// can not be instantiated, use <see cref="Instance"/> instead. 
        /// </summary> 
        protected DomainObjectsRepository() 
        { 
    
        } 
    
        static DomainObjectsRepository() 
        { 
         Instance = new DomainObjectsRepository(); 
        } 
    
        public static DomainObjectsRepository Instance { get; set; } 
    
    
        public virtual ICustomerDao GetCustomerDao() 
        { 
         return new CustomerDao(); 
        } 
    } 
    
    public class DomainObjectsRepositoryMock : DomainObjectsRepository 
    { 
        public override ICustomerDao GetCustomerDao() 
        { 
         return new CustomerDaoMock(); 
        } 
    } 
    
    Questions connexes