если Вы интересуетесь экранными демонстрациями, контроль лето nhibernate учебные руководства. Они - execllent способ встать и выполнение
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
, и у моих классов глобальной конфигурации есть только одна причина для изменения.
Чтобы он был полностью закрыт, у вас может быть статический инициализатор для каждой регистрации сопоставления, но это было бы излишним.
Некоторые вещи на самом деле полезно иметь до некоторой степени централизации с точки зрения с точки зрения возможности обратного проектирования.
В NInject существует понятие наличия модуля
для каждого проекта или подсистемы (набора проектов), что кажется разумным компромиссом.
Ому, я борюсь с аналогичными вопросами, когда дело доходит до начальной загрузки контейнера IoC в процедуру запуска моего приложения. Что касается IoC, то руководство, которое мне было дано, указывает на преимущество централизации вашей конфигурации, а не разбрызгивания ее по всему приложению при добавлении изменений. Я думаю, что для настройки AutoMapper преимущество централизации гораздо менее важно. Если вы можете поместить свой контейнер AutoMapper в свой контейнер IoC или Service Locator, я согласен с предложением Рубена Бартелинка настроить сопоставления один раз для каждой сборки или в статических конструкторах или в чем-то децентрализованном.
В основном, я считаю, что это вопрос решения, хотите ли вы централизовать загрузку или децентрализовать ее. Если вас беспокоит принцип открытости / закрытости в вашей рутине запуска, пойти на децентрализацию. Но ваша приверженность OCP может быть снижена в обмен на ценность всей вашей начальной загрузки, выполненной в одном месте. Другой вариант - заставить загрузчик сканировать определенные сборки на предмет реестров, если в AutoMapper есть такая концепция.
Во всяком случае, это принцип единственной ответственности, который вы нарушаете, поскольку у этого класса есть несколько причин для изменения.
Лично у меня был бы класс ConfigureAutoMapper, с которым была выполнена вся моя конфигурация для AutoMapper. Но можно утверждать, что все зависит от личного выбора.