Я бы сказал, что вы нарушаете два принципа: принцип единой ответственности (SRP) и принцип открытого / закрытого (OCP).
Вы нарушаете SRP, потому что у класса начальной загрузки есть более чем одна причина для изменения: если вы изменяете привязку модели или конфигурацию автоматического сопоставления.
Вы бы нарушили OCP, если бы добавили дополнительный код начальной загрузки для настройки другого подкомпонента системы.
Как я обычно это делаю, я определяю следующий интерфейс.
public interface IGlobalConfiguration
{
void Configure();
}
Для каждого компонента в системе, который нуждается в начальной загрузке, я бы создал класс, реализующий этот интерфейс.
public class AutoMapperGlobalConfiguration : IGlobalConfiguration
{
private readonly IConfiguration configuration;
public AutoMapperGlobalConfiguration(IConfiguration configuration)
{
this.configuration = configuration;
}
public void Configure()
{
// Add AutoMapper configuration here.
}
}
public class ModelBindersGlobalConfiguration : IGlobalConfiguration
{
private readonly ModelBinderDictionary binders;
public ModelBindersGlobalConfiguration(ModelBinderDictionary binders)
{
this.binders = binders;
}
public void Configure()
{
// Add model binding configuration here.
}
}
Я использую Ninject для внедрения зависимостей. 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
, и у моих классов глобальной конфигурации есть только одна причина для изменения.