ASP.Net MVC5 и StructureMap4 - упрощенный подход

Интегрируя StructureMap.MVC5 в веб-приложение ASP.Net MVC5, понял, что оно использует версию SM3.1, а не 4+. Затем попытался взять файлы, включенные в этот Nuget, и изменить его для SM4, но там было много кода и несколько несовместимых вызовов через SM3.1 и SM4.

После этого я написал простой IoC, как показано ниже. Нужны советы по поводу ее недостатков и неэффективности по сравнению с версией Nuget, указанной здесь.

Определить реестр по умолчанию

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

        For<IContext<SomeClass>>().Use<MyContext>();
    }
}

Создать статический контейнер

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

Переопределить фабрику контроллеров

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

Зарегистрируйтесь в Global.asax

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

Это работает, но беспокоюсь, что я слишком упрощаю это, и это может привести к другим проблемам. Ищете понимание проблем с этим подходом.

1 ответ

Есть две вещи. Это необходимо в DefaultRegistry для более надежной регистрации контроллеров:

scan.With(new ControllerConvention());

Вот ControllerConvention для 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());
        }
    }
}

Во-вторых, используя DependencyResolver предпочтительнее создания собственного DefaultControllerFactory, Реализация MVC богаче, как вы можете видеть здесь. Вы можете скопировать это на свое усмотрение, но это не будущее, и, что самое главное, не нужно, потому что вы можете просто использовать DependencyResolver, сохраняя ваш код проще. В основном, используйте классы StructuremapMvcа также StructureMapDependencyScope вы получаете от установки StructureMap.MVC5. Вы можете перенести инициализацию и избавиться от StructuremapMvc на Global.asax, если вы предпочитаете.

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));
}
Другие вопросы по тегам