Nous construisons une application RH assez grande dans ASP.NET MVC, et jusqu'à présent, nos contrôleurs deviennent assez volumineux. Par exemple, nous avons un contrôleur des employés et toutes les vues des employés sont incluses (informations personnelles, retenues sur les employés, personnes à charge, etc.). Chacune de ces vues peut avoir plusieurs actions ou sous-vues (par exemple CRUD). Chaque action est relativement petite, mais les contrôleurs peuvent avoir des dizaines de fonctions.
Existe-t-il des meilleures pratiques pour fractionner les contrôleurs? Au lieu d'avoir un contrôleur Employé avec des dizaines de vues, serait-il préférable d'avoir un contrôleur pour chaque sous-type (c'est-à-dire EmployeePersonalInfoController, EmployeeDeductionController, EmployeeDependentController)?
Et enfin, est-ce même important?
Clarification mise à jour
Ma préoccupation initiale concernait les actions du CRUD. Par exemple, considérons Créer et supprimer ...
Actions en cours dans EmployeeController :
CreateEmployee()
DeleteEmployee()
CreateEmployeeDeduction()
DeleteEmployeeDeduction()
CreateDependent()
DeleteDependent()
etc.
Si les contrôleurs étaient divisés:
EmployeeController
Create()
Delete()
EmployeeDeductionController
Create()
Delete()
EmployeeDependentController
Create()
Delete()
EmployeeBenefitController
Create()
Delete()
etc.
Dans le 1er scénario, nos ~ 100 écrans sont divisés en 8-10 grands contrôleurs. Dans le second, j'aurais probablement ~ 50 contrôleurs.
À mon humble avis, si vous gardez le code dans vos contrôleurs, cela n'a pas vraiment d'importance.
La plupart de votre code se produirait dans une couche métier quelque part, non? Si tel est le cas, tout ce que vous faites réellement dans votre contrôleur est de retourner des données à la vue. Comme cela devrait être.
Je ne sais pas vraiment si je suis fan de séparer les contrôleurs en sous-types. Alors que vous devez maintenir la séparation des préoccupations, je pense que les sous-types vont un peu trop loin.
Vous pouvez jeter un oeil à ce post pour voir si cela aide. même vue différents chemins
Cela peut être une meilleure solution que d'utiliser une approche de sous-type que vous avez suggérée.
Classes partielles vous permet de répartir votre classe sur plusieurs fichiers. De cette façon, vous pouvez regrouper les zones pertinentes de votre contrôleur dans des fichiers séparés, et pourtant elles feront toujours partie du même contrôleur. par exemple.
EmployeeDeductionController.cs
public partial class EmployeeController
{
public ActionResult Deduct()
{
}
// etc
}
EmployeeBenefitController.cs
public partial class EmployeeController
{
public ActionResult GiveBenefit()
{
}
// etc
}
Je ne voudrais pas avoir 50 contrôleurs. En ce moment, j'en ai 16 dans ma candidature et ça me va. Si vous avez 50 contrôleurs, vous aurez également 50 dossiers de niveau supérieur pour les vues. Il sera difficile de trouver la vue et le contrôleur sur lesquels vous devez travailler. Comme d'autres l'ont mentionné, les actions sont généralement courtes et ce n'est pas si mal d'en avoir deux dans votre contrôleur.
J'ai essayé d'avoir 1 contrôleur par partie système. Je définis une partie système en prenant mon schéma de base de données et en dessinant une ligne autour de tables qui vont ensemble.
Pourquoi ne pas les regrouper?
Avoir une structure comme,
employee/payroll/
employee/payroll/giveraise
employee/payroll/manage401k
employee/general/
employee/general/address
employee/general/emergencycontact
Vous pouvez maintenant avoir un contrôleur de paie qui gère les actions liées à la paie et un contrôleur général qui gère les détails réguliers d'un employé.
Une autre approche que nous avons utilisée est d'avoir une ControllerBase pour garder les préoccupations transversales au même endroit pour les opérations CRUD. Ce contrôleur déclare les opérations courantes et inclut des points d'extension pour les éléments d'entité spécifiques. Nous avons eu trop de duplication de code sans quelque chose comme ça.
Ensuite, vous héritez de ce contrôleur et en créez un par entité. Et oui, il y a beaucoup de contrôleurs mais avec autant d'écrans, je ne pense pas que ce sera le problème principal.
La plupart des actions acceptent un modèle complexe et nous jouons ensuite avec les classeurs de modèle pour éliminer l'encombrement des contrôleurs. Vous pouvez voir un bon article à ce sujet ici .
Ensuite, utiliser des zones comme @Odd le suggère est une bonne idée, au moins pour séparer les vues car lorsque vous en avez beaucoup, c'est un gâchis.
Espérons que ASP.NET MVC v2 nous apportera des zones et des vues d'encapsulation dans différents assemblys (en fait, cela peut être fait maintenant en étendant la classe VirtualPathProvider).
Les contrôleurs sont censés être des conteneurs pour les actions dans un même contexte. C'EST À DIRE. un contrôleur client aurait des actions relatives au contrôle des clients. Ceci est particulièrement adapté au CRUD. J'irais avec moins de contrôleurs plus grands pour cette raison. Cela dit, c'est vraiment à vous, en tant qu'architecte d'application, de choisir la manière qui convient le mieux à votre code et ce n'est pas parce que c'est plus courant de le faire dans un sens que vous le devez.
Si vous avez de grandes quantités de code, je vous suggère de regarder dans les zones ASP.NET MVC. Vous pouvez trouver d'excellents articles à ce sujet ici dans le blog de Scott G et ici dans le blog de Steve Sanderson . Si vous avez autant de contrôleurs, cela pourrait vous convenir.
Je viens de penser après avoir relu votre message, je soupçonne que votre exemple ne se rapproche pas du niveau de complication que vous avez dans votre code. Peut-être que cela pourrait aider si vous avez publié une situation où vous ne saviez pas si c'était une bonne idée de diviser votre contrôleur qui est plus spécifique (et moins CRUDDY, car CRUD est assez simple).
J'organiserais les contrôleurs à peu près autour des cas d'utilisation et de leur regroupement logique. Par exemple. si vous disposez de plusieurs cas d'utilisation de type administratif/RH susceptibles d'être disponibles pour un groupe limité de personnes, regroupez-les dans un seul contrôleur. D'autres contrôleurs pourraient être organisés autour d'objets de modèle de domaine spécifiques - par exemple gestion des congés en libre-service, requêtes salariales, etc.
N'oubliez pas que, autant que possible, vous ne devriez pas avoir de logique métier de base dans vos contrôleurs. Ils implémentent vraiment le comportement frontal tandis que les règles système réelles devraient se trouver dans votre modèle de domaine et votre couche de service. Tant que vous gardez les choses à peu près dans la bonne couche et raisonnablement découplées, vous ne pouvez pas vous tromper trop sur la façon dont vous placez les opérations individuelles dans vos contrôleurs.