问题
While integrating StructureMap.MVC5 to an ASP.Net MVC5 web application, realized that it uses 3.1 version of SM and not 4+. Then tried taking the files included in this Nuget and changing it for SM4, but a lot of code was there and several incompatible calls across SM3.1 and SM4.
With that, I ended up writing a simple IoC as below. Looking for advise on its shortfalls and what inefficiencies this have compared to the Nuget version linked here.
Define Default Registry
public class DefaultRegistry : Registry
{
public DefaultRegistry() {
Scan(
scan => {
scan.Assembly("MyAssembly");
scan.WithDefaultConventions();
});
For<IContext<SomeClass>>().Use<MyContext>();
}
}
Create a Static Container
public static class IoC {
private static IContainer container = new Container(c => c.AddRegistry<DefaultRegistry>());
public static IContainer Container { get { return container; } }
}
Override the Controller Factory
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (IController)IoC.Container.GetInstance(controllerType);
}
}
Register in Global.asax
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
}
This works, but worried that am over-simplifying it and this might introduce other issues. Looking for insights into problems with this approach.
回答1:
There's two things. You need this in the DefaultRegistry to have a more robust registration of Controllers:
scan.With(new ControllerConvention());
Here is the ControllerConvention for StructureMap 4:
public class ControllerConvention : IRegistrationConvention
{
public void ScanTypes(TypeSet types, Registry registry)
{
foreach (var type in types.AllTypes().Where(type => type.CanBeCastTo<Controller>() && !type.IsAbstract))
{
registry.For(type).LifecycleIs(new UniquePerRequestLifecycle());
}
}
}
Second, using the DependencyResolver
is preferable over creating your own DefaultControllerFactory
. MVC's implementation is richer as you can see here. You could copy that to your own but that's not future proof and most of all, not needed because you can just use DependencyResolver
, keeping your code simpler. Basically, use the classes StructuremapMvc
and StructureMapDependencyScope
you get from installing StructureMap.MVC5. You could move the initialization and disposing from StructuremapMvc
to the Global.asax if you prefer.
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));
}
来源:https://stackoverflow.com/questions/35837920/asp-net-mvc5-and-structuremap4-simplified-approach