ASP.Net MVC5 and StructureMap4 - Simplified Approach

只谈情不闲聊 提交于 2020-01-14 02:44:06

问题


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 StructuremapMvcand 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!