6
votes

Éviter l'utilisation de SelectList dans la couche d'entreprise (MVC 3)

Je travaille sur une application de MVC 3 assez importante et je suis dans un problème qui ne mène pas parfaitement à moi. Cette question prend un peu mis en place pour comprendre, alors voici les locaux que je travaille actuellement sur:

  • Les vues doivent être fortement typées (ViewBag / ViewData doit être évitée)
  • Parce que les vues sont fortement typées, voir les objets de modèle doivent être créés qui encapsulent toutes les données dont la vue doit afficher
  • Lorsque nous avons besoin de menus déroulants, nous devrions avoir deux propriétés:
    1. une propriété dans le modèle qui stocke la valeur sélectionnée de la liste déroulante
    2. A Sélectionnez la propriété dans le modèle de vue qui représente les éléments de la liste déroulante
    3. La vue elle-même utilise toujours le @ html.dropdownlistor () méthode d'assistance
    4. Nous utilisons l'entité Framework 4 et la laissons générer des cours d'entité à partir de notre base de données déjà conçue
    5. Pour éviter les doubles emplois et profiter de LINQ, nous ne créons pas nos propres classes commerciales / modèles distinctes, mais ajoutant aux classes partielles générées par le cadre d'entité
    6. Ces classes partielles que nous écrivons sont situées dans la couche d'entreprise pour que tout compilait correctement
    7. La plupart des classes de modèle ont un modèle d'éditeur partagé qui peut être utilisé dans plusieurs vues

      Voici là où le problème est entré. Le type de modèle du modèle d'éditeur partagé est défini sur la classe modèle. Cela signifie que la vue partielle constitue le modèle de l'éditeur n'a pas accès à l'objet de modèle de vue contenant dans lequel la liste des éléments déroulants est stockée.

      J'ai pu "résoudre" cela en ajoutant une propriété SELECTLIST directement sur la classe de modèle dans la couche d'entreprise au lieu de le garder dans le modèle de vue. Mais la classe SELECTLIST est spécifique à MVC, qui signifie à son tour que ma couche d'entreprise a une dépendance sur MVC. Cela ne me semble pas juste parce que le BL devrait être agnostique à l'interface utilisateur.

      Quelqu'un d'autre a-t-il rencontré ce problème? Comment dois-je résoudre ce problème? Il est également possible que l'un de mes locaux aient mal.


0 commentaires

3 Réponses :


4
votes

Tout semble très agréable et bon design jusqu'à ce point (qui n'est pas surprenant, car c'est ce point qui vous cause des maux de tête: -)):

La plupart des classes de modèle ont un modèle d'éditeur partagé qui peut être utilisé dans plusieurs vues

Voici les modèles qui doivent avoir des modèles de rédaction et non des modèles EF. Et comme la vue des modèles est spécifique aux exigences de la vue, vous êtes libre de mettre les informations dont vous avez besoin, comme dans ce cas, le Sélectionnez . Donc, ne définissez pas simplement un modèle de vue racine qui contient vos modèles EF en tant que propriétés (ce n'est pas un modèle de vue). Définissez un modèle de vue conçu pour répondre aux exigences de la vue particulière. Ne mettez pas une seule classe EF dans votre hiérarchie du modèle de vue et vous verrez à quel point votre vie sera plus simple: -)

Et ne vous inquiétez pas si vous avez des propriétés dupliquées dans vos modèles de vue. C'est ce que ces classes sont conçues pour. Aussi Simpleapper pourrait considérablement simplifier la mappage entre vos modèles et voir des modèles.


3 commentaires

Je vois ce que vous obtenez, mais je suis toujours en conflit. Si nous n'utilisons pas les classes de modèle du tout (pas même les propriétés du modèle de vue), il semble que nous ayons l'impression que nous écrivions beaucoup de code qui consiste uniquement à des propriétés déjà dupliquées ailleurs. Il semble également que nous abandonnions certains des avantages de EF, comme sa capacité à suivre les modifications lorsqu'ils sont utilisés avec les contrôleurs UpdateModel méthode. Nous utilisons déjà automapper pour quelques choses, de sorte que cette partie n'est pas une grosse affaire.


@Shea - Je ne pense pas que les modifications de la piste des entités EF fonctionnent réellement dans des scénarios Web, car vous perdez le suivi une fois la réponse au client.


Voir ma réponse à cette question sur la manière dont nous l'utilisons: Stackoverflow.com/Questtions/5022943/... . Bien que je suppose que si tous les noms de propriété correspondent, cela pourrait toujours fonctionner?



1
votes

Vous avez 2 solution principale IMHO:

1. Générez des dtos / modèles pour les entités logiques de votre entreprise forts> p>

Vous pouvez utiliser automapper à minimiser le code de copie. Vous obtiendrez une belle séparation entre votre vision et votre logique commerciale. Cela peut toutefois consommer du temps pour votre grande application. P>

2. Utilisez des méthodes d'extension strong> p>

au lieu de déclarer une propriété sélectionnée dans la classe partielle d'entité EF et polluant votre logique commerciale avec le code associé à la vue Créer une méthode d'extention pour votre fichier EF. Vous pouvez déplacer votre code associé à la vue au projet Web à partir de BL et garder Type-Safety. P>

Exemple: EM> P>

Assemblée logique d'entreprise P> XXX PRE>

Assemblage Web P>

public static class FooTableExtensions
{
    public static SelectList GetSelectList(this IEnumerable<FooTable> fooTables)
    {
        return new SelectList(); // Create your select list from FooTables here.
    }
}


1 commentaires

La solution numéro 1 est la façon dont nous avons initialement commencé à développer notre application et nous avons décidé que l'approche ne valait pas la peine d'effort supplémentaire considérable. Il lance également certains des avantages d'utiliser Linq (comme exécution différée). Avez-vous des exemples de solution numéro 2? Comment cela fonctionnerait-il dans la pratique?



0
votes

Eh bien, nous avons fini par prendre la solution simple. Dans la couche d'entreprise, nous venons de modifier le type à l'ancien d'objets . Je pensais que, quelle que soit la couche de présentation, il aura besoin d'une sorte de liste pour contenir les options disponibles.

Je sais que ce n'est pas super propre qu'au @darin et @jakub, mais je ne vois pas que notre résultat final n'est pas différent de cette façon, sauf que nous avons évité de devoir écrire et / ou mettre en place un tas des mappages entre objets.


0 commentaires