Конфигурирование Автокартопостроителя в Bootstrapper нарушает Открыто закрытый Принцип?

если Вы интересуетесь экранными демонстрациями, контроль лето nhibernate учебные руководства. Они - execllent способ встать и выполнение

35
задан Péter Török 17 October 2010 в 13:59
поделиться

4 ответа

using static IronRuby.Ruby;

class Print1To100WithoutLoopsDemo
{
    static void Main() => 
      CreateEngine().Execute("(1..100).each {|i| System::Console.write_line i }");
}

Эй, а почему бы и нет?

IConfiguration является базовой реализацией статического класса AutoMapper , а ModelBinderDictionary является объектом ModelBinders.Binder . Затем я определил бы NinjectModule , который будет сканировать указанную сборку на предмет любого класса, реализующего интерфейс IGlobalConfiguration , и добавить эти классы в составную часть.

public class GlobalConfigurationModule : NinjectModule
{
    private readonly Assembly assembly;

    public GlobalConfigurationModule() 
        : this(Assembly.GetExecutingAssembly()) { }

    public GlobalConfigurationModule(Assembly assembly)
    {
        this.assembly = assembly;
    }

    public override void Load()
    {
        GlobalConfigurationComposite composite = 
            new GlobalConfigurationComposite();

        IEnumerable<Type> types = 
            assembly.GetExportedTypes().GetTypeOf<IGlobalConfiguration>()
                .SkipAnyTypeOf<IComposite<IGlobalConfiguration>>();

        foreach (var type in types)
        {
            IGlobalConfiguration configuration = 
                (IGlobalConfiguration)Kernel.Get(type);
            composite.Add(configuration);
        }

        Bind<IGlobalConfiguration>().ToConstant(composite);
    }
}

Затем я бы добавил следующий код в файл Global.asax.

public class MvcApplication : HttpApplication
{
    public void Application_Start()
    {
        IKernel kernel = new StandardKernel(
            new AutoMapperModule(),
            new MvcModule(),
            new GlobalConfigurationModule()
        );

        Kernel.Get<IGlobalConfiguration>().Configure();
    }
}

Теперь мой код начальной загрузки соответствует как SRP, так и OCP. Я могу легко добавить дополнительный код начальной загрузки, создав класс, реализующий интерфейс IGlobalConfiguration , и у моих классов глобальной конфигурации есть только одна причина для изменения.

Затем я определил NinjectModule , который будет сканировать указанную сборку на предмет любого класса, реализующего интерфейс IGlobalConfiguration , и добавить эти классы в составную часть.

public class GlobalConfigurationModule : NinjectModule
{
    private readonly Assembly assembly;

    public GlobalConfigurationModule() 
        : this(Assembly.GetExecutingAssembly()) { }

    public GlobalConfigurationModule(Assembly assembly)
    {
        this.assembly = assembly;
    }

    public override void Load()
    {
        GlobalConfigurationComposite composite = 
            new GlobalConfigurationComposite();

        IEnumerable<Type> types = 
            assembly.GetExportedTypes().GetTypeOf<IGlobalConfiguration>()
                .SkipAnyTypeOf<IComposite<IGlobalConfiguration>>();

        foreach (var type in types)
        {
            IGlobalConfiguration configuration = 
                (IGlobalConfiguration)Kernel.Get(type);
            composite.Add(configuration);
        }

        Bind<IGlobalConfiguration>().ToConstant(composite);
    }
}

Затем я бы добавил следующий код в файл Global.asax.

public class MvcApplication : HttpApplication
{
    public void Application_Start()
    {
        IKernel kernel = new StandardKernel(
            new AutoMapperModule(),
            new MvcModule(),
            new GlobalConfigurationModule()
        );

        Kernel.Get<IGlobalConfiguration>().Configure();
    }
}

Теперь мой код начальной загрузки соответствует как SRP, так и OCP. Я могу легко добавить дополнительный код начальной загрузки, создав класс, реализующий интерфейс IGlobalConfiguration , и у моих классов глобальной конфигурации есть только одна причина для изменения.

Затем я определил бы NinjectModule , который будет сканировать указанную сборку на предмет любого класса, реализующего интерфейс IGlobalConfiguration , и добавить эти классы в составную часть.

public class GlobalConfigurationModule : NinjectModule
{
    private readonly Assembly assembly;

    public GlobalConfigurationModule() 
        : this(Assembly.GetExecutingAssembly()) { }

    public GlobalConfigurationModule(Assembly assembly)
    {
        this.assembly = assembly;
    }

    public override void Load()
    {
        GlobalConfigurationComposite composite = 
            new GlobalConfigurationComposite();

        IEnumerable<Type> types = 
            assembly.GetExportedTypes().GetTypeOf<IGlobalConfiguration>()
                .SkipAnyTypeOf<IComposite<IGlobalConfiguration>>();

        foreach (var type in types)
        {
            IGlobalConfiguration configuration = 
                (IGlobalConfiguration)Kernel.Get(type);
            composite.Add(configuration);
        }

        Bind<IGlobalConfiguration>().ToConstant(composite);
    }
}

Затем я бы добавил следующий код в файл Global.asax.

public class MvcApplication : HttpApplication
{
    public void Application_Start()
    {
        IKernel kernel = new StandardKernel(
            new AutoMapperModule(),
            new MvcModule(),
            new GlobalConfigurationModule()
        );

        Kernel.Get<IGlobalConfiguration>().Configure();
    }
}

Теперь мой код начальной загрузки соответствует как SRP, так и OCP. Я могу легко добавить дополнительный код начальной загрузки, создав класс, реализующий интерфейс IGlobalConfiguration , и у моих классов глобальной конфигурации есть только одна причина для изменения.

39
ответ дан 27 November 2019 в 07:16
поделиться

Чтобы он был полностью закрыт, у вас может быть статический инициализатор для каждой регистрации сопоставления, но это было бы излишним.

Некоторые вещи на самом деле полезно иметь до некоторой степени централизации с точки зрения с точки зрения возможности обратного проектирования.

В NInject существует понятие наличия модуля для каждого проекта или подсистемы (набора проектов), что кажется разумным компромиссом.

3
ответ дан 27 November 2019 в 07:16
поделиться

Ому, я борюсь с аналогичными вопросами, когда дело доходит до начальной загрузки контейнера IoC в процедуру запуска моего приложения. Что касается IoC, то руководство, которое мне было дано, указывает на преимущество централизации вашей конфигурации, а не разбрызгивания ее по всему приложению при добавлении изменений. Я думаю, что для настройки AutoMapper преимущество централизации гораздо менее важно. Если вы можете поместить свой контейнер AutoMapper в свой контейнер IoC или Service Locator, я согласен с предложением Рубена Бартелинка настроить сопоставления один раз для каждой сборки или в статических конструкторах или в чем-то децентрализованном.

В основном, я считаю, что это вопрос решения, хотите ли вы централизовать загрузку или децентрализовать ее. Если вас беспокоит принцип открытости / закрытости в вашей рутине запуска, пойти на децентрализацию. Но ваша приверженность OCP может быть снижена в обмен на ценность всей вашей начальной загрузки, выполненной в одном месте. Другой вариант - заставить загрузчик сканировать определенные сборки на предмет реестров, если в AutoMapper есть такая концепция.

2
ответ дан 27 November 2019 в 07:16
поделиться

Во всяком случае, это принцип единственной ответственности, который вы нарушаете, поскольку у этого класса есть несколько причин для изменения.

Лично у меня был бы класс ConfigureAutoMapper, с которым была выполнена вся моя конфигурация для AutoMapper. Но можно утверждать, что все зависит от личного выбора.

2
ответ дан 27 November 2019 в 07:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: