2010-03-25 9 views
1

Je souhaite que mes classes concrètes soient séparées de mes vues. Sans utiliser de vues fortement typées, je vais bien. J'utilise simplement une grande liste de paramètres dans les signatures de la méthode du contrôleur, puis j'utilise mes méthodes de fabrication de couche de service pour créer mes objets concrets. Cela me convient parfaitement, mais après un peu de lecture, j'ai réalisé qu'il était littéralement impossible pour une méthode de contrôleur d'accepter une interface comme paramètre de méthode - parce qu'elle n'a aucun moyen de l'instancier . Impossible de créer une vue fortement typée à l'aide d'une interface via l'EDI (ce qui est logique).ASP.NET MVC 2 - Comment utiliser une interface comme type pour une vue fortement typée

Donc, ma question. Est-il possible de dire au contrôleur comment instancier le paramètre d'interface en utilisant mes méthodes de fabrication de couche de service?

Je voudrais convertir:

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
[UrlRoute(Path = "Application/Edit/{id}")] 
public ActionResult Edit(String id, String TypeCode, String TimeCode, String[] SelectedSchoolSystems, 
      String PositionChoice1, String PositionChoice2, String PositionChoice3, String Reason, String LocationPreference, 
      String AvailableDate, String RecipientsNotSelected, String RecipientsSelected) { 

    //New blank app 
    IApplication _application = ApplicationService.GetById(id); 

à quelque chose comme

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
[UrlRoute(Path = "Application/Edit/{id}")] 
public ActionResult Edit(String id, IApplication app) { 

      //Don't need to do this anymore 
      //IApplication _application = ApplicationService.GetById(id); 
+0

Merci pour l'excellente entrée tout le monde. Énorme aide. – Rake36

+0

Cela fait plusieurs mois, mais après beaucoup plus de codage - je me suis rendu compte que même si le classeur de modèle personnalisé est probablement la bonne réponse, l'utilisation de modèles de vue fortement typés fonctionne le mieux pour moi. La clé étant que les View Models sont assez différents des objets de ma base de données. – Rake36

Répondre

2

Vous devez vue couche de modèle. Il peut être judicieux de faire abstraction des entités de couche de gestion à l'aide d'interfaces, mais cela n'a pas beaucoup de sens d'abstraire des entités spécifiques d'une application Web (dans la plupart des cas, je suppose). Cela vous permettrait de coder contre les implémentations.

En essayant de lier des entités à partir de Form sans accéder à la base de données, vous aurez aussi beaucoup de problèmes.

+0

Peut-être que je mélange mal les architectures, mais j'ai déjà une couche d'accès aux données et une couche de service - donc je traite le site MVC comme couche de présentation et je ne veux pas créer de modèles de visualisation de mes classes de couche de données. Suis-je trompé en pensant que l'interface devrait être assez bonne? – Rake36

+0

@ Rake36 Cela pourrait suffire dans certains cas. Cela dépend toujours du contexte. Je dis simplement que l'ajout d'un modèle de vue correct résoudrait facilement ce problème particulier (mais augmenterait votre base de code avec les modèles de vue et la logique de mappage). –

+0

@ Rake36 Vous trouverez peut-être utile cet article - http://bit.ly/9Bxpfj Je suppose que le 'couplage externe 'est ce qui fait problème dans votre cas. –

1

modèle personnalisé obligatoire. Il suffit que le classeur modèle crée une instance d'une classe dérivée et la renvoie en tant qu'interface.

D'autre part, pourquoi? Généralement, vous utiliseriez des modèles spécifiques à la vue pour la vue et les paramètres du contrôleur. Chaque vue/action a des besoins de modèle spécifiques. Je peux comprendre pourquoi vous aimeriez les dériver d'une interface ou d'une classe abstraite commune - ainsi, par exemple, votre page maître a un ensemble d'informations communes qu'elle peut utiliser, mais pourquoi une action spécifique doit-elle jamais recevoir les données? comme une abstraction? Ne connaît-il pas exactement le type de données dont il a besoin et utilise-t-il simplement la classe dérivée correcte comme type de paramètre?

+0

Le contrôleur n'a aucune idée de la classe dérivée à utiliser. Seule la couche de service le fait. J'avais pensé que je pourrais peut-être aller de l'avant et créer des modèles spécifiques à la vue, puis les utiliser comme paramètres pour les méthodes de couche de service. J'essayais d'éviter d'avoir à effectuer une sorte de correspondance entre les modèles de vue et mes classes concrètes. Cela a-t-il du sens? – Rake36

+0

Je comprends ce que vous dites, mais je pense que vous êtes sur la mauvaise route. J'ai constaté que les choses fonctionnent beaucoup mieux lorsque vous avez des modèles de vue et de données. Invariablement, j'ai trouvé que j'ai besoin d'augmenter mes modèles de données avec des données supplémentaires pour la vue et l'encapsuler dans un modèle spécifique à la vue semble être la meilleure méthode. – tvanfosson

+0

Merci.Je vais essayer cette idée ainsi que l'approche de liaison de modèle personnalisé. Je posterai ici avec mes résultats. – Rake36

1

Vous pouvez écrire un liant modèle personnalisé qui instancier le type correct:

public class MyModelBinder: DefaultModelBinder 
{ 
    protected override object CreateModel(
     ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     Type modelType 
    ) 
    { 
     return // ... instantiate your model here 
    } 
} 

Et puis:

public ActionResult Edit(
    string id, 
    [ModelBinder(typeof(MyModelBinder))] IApplication app 
) 
{ 
    ... 
} 
+0

Je n'avais pas regardé de trop près les classeurs personnalisés. Merci pour l'exemple. – Rake36

Questions connexes