Nous utilisons des tonnes de MEF dans ASP.NET MVC, bien que la plupart d'entre eux se trouvent à un niveau inférieur à celui du contrôleur, comme dans nos modules de niveau inférieur qui utilisent des plugins MEF pour vérifier les autorisations et valider les données.
Cependant, nous utilisons également une approche plus composable pour nos contrôleurs. Les vues sont plus délicates, mais nous avons en fait complètement éliminé l'utilisation de vues ASP.NET MVC ordinaires et stockons nos vues Razor sous forme de snippets dans une base de données. Nos contrôleurs demandent ensuite à un moteur de modèles une vue au moment de l'exécution et rendent ContentResult à la réponse au lieu de renvoyer View("Nom de la vue"), etc.
Nos plugins MEF ont tous des propriétés d'identification qui nous permettent d'effectuer un remplacement en cascade au moment de l'exécution pour déterminer quel plugin/classe doit être utilisé dans un but donné. L'exemple le plus simple à démontrer est celui d'une application qui a une base commune, mais qui est déployée dans plus de 50 implémentations qui ont chacune la possibilité de remplacer la fonctionnalité de base.
Ainsi, vous pourriez avoir quelque chose comme un IUserController qui inclut des méthodes pour "Login", "Logout", etc.
En plus de cette fonctionnalité réelle, nous ajouterions à l'interface une propriété GUID en lecture seule appelée "SiteId". Chaque implémentation coderait alors en dur le SiteId auquel elle est destinée. Pour l'implémentation "par défaut" dans le code principal, elle renverrait "Guid.Empty".
Ensuite, lorsque nous invoquons le MEF et que nous cherchons quelle implémentation de IUserController utiliser, nous faisons un ImportMany de toutes ces implémentations dans une liste, puis nous utilisons LINQ pour interroger les propriétés afin de déterminer laquelle utiliser :
var _currentUserController = _availableUserControllers.FirstOrDefault(
c=>c.SiteId == AppSettings.SiteId);
if(_currentUserController == null){
//There is no site-specific override
_currentUserController = _availableUserControllers.FirstOrDefault(
c=>c.SiteId == Guid.Empty);
}
Pour faire cela avec les contrôleurs, votre meilleure chance est de regarder certaines des implémentations des usines de contrôleurs basées sur le MEF qui existent sur le web.
Cependant, comme je l'ai dit, nous faisons presque tout cela à un niveau inférieur et nous demandons à nos modules ou aux contrôleurs de faire ce genre de recherche pour déterminer les plugins à exécuter.