ASP.Net MVC5 et StructureMap4 – Approche simplifiée

Lors de l’intégration de StructureMap.MVC5 à une application Web ASP.Net MVC5, il s’est rendu compte qu’il utilisait la version 3.1 de SM et non 4+. Puis essayé de prendre les fichiers inclus dans ce Nuget et de le changer pour SM4, mais il y avait beaucoup de code et plusieurs appels incompatibles entre SM3.1 et SM4.

Avec cela, j’ai fini par écrire un simple IoC comme ci-dessous. Vous cherchez des conseils sur ses lacunes et ses inefficacités par rapport à la version de Nuget liée ici.

Définir le registre par défaut

public class DefaultRegistry : Registry { public DefaultRegistry() { Scan( scan => { scan.Assembly("MyAssembly"); scan.WithDefaultConventions(); }); For<IContext>().Use(); } } 

Créer un conteneur statique

 public static class IoC { private static IContainer container = new Container(c => c.AddRegistry()); public static IContainer Container { get { return container; } } } 

Ignorer la fabrique de contrôleurs

 public class StructureMapControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return (IController)IoC.Container.GetInstance(controllerType); } } 

Inscrivez-vous à Global.asax

 protected void Application_Start() { ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); } 

Cela fonctionne, mais je crains que je ne le simplifie trop et que cela puisse introduire d’autres problèmes. Vous cherchez des idées sur les problèmes posés par cette approche.

Il y a deux choses. Vous avez besoin de cela dans le DefaultRegistry pour avoir un enregistrement plus robuste des contrôleurs:

 scan.With(new ControllerConvention()); 

Voici la ControllerConvention pour StructureMap 4:

 public class ControllerConvention : IRegistrationConvention { public void ScanTypes(TypeSet types, Registry registry) { foreach (var type in types.AllTypes().Where(type => type.CanBeCastTo() && !type.IsAbstract)) { registry.For(type).LifecycleIs(new UniquePerRequestLifecycle()); } } } 

Deuxièmement, utiliser DependencyResolver est préférable à la création de votre propre DefaultControllerFactory . L’implémentation de MVC est plus riche, comme vous pouvez le voir ici . Vous pouvez copier cela dans le vôtre, mais ce n’est pas une preuve pour le futur et surtout pas nécessaire car vous pouvez simplement utiliser DependencyResolver , ce qui simplifie votre code. En gros, utilisez les classes StructuremapMvc et StructureMapDependencyScope vous obtenez en installant StructureMap.MVC5. Vous pouvez déplacer l’initialisation et la suppression de StructuremapMvc vers le fichier Global.asax si vous préférez.

 public static StructureMapDependencyScope StructureMapDependencyScope { get; set; } public static void End() { StructureMapDependencyScope.Dispose(); } public static void Start() { IContainer container = IoC.Initialize(); StructureMapDependencyScope = new StructureMapDependencyScope(container); DependencyResolver.SetResolver(StructureMapDependencyScope); DynamicModuleUtility.RegisterModule(typeof(StructureMapScopeModule)); }