Omu*_*Omu 35 .net bootstrapping automapper open-closed-principle solid-principles
我在引导程序配置Automapper和我打电话Bootstrap()
的 Application_Start()
,我一直在说,这是错误的,因为我要修改我的Bootstrapper
每一次我必须添加一个新的映射类,所以我违反了开闭原则.
你觉得怎么样,我真的违反了这个原则吗?
public static class Bootstrapper
{
public static void BootStrap()
{
ModelBinders.Binders.DefaultBinder = new MyModelBinder();
InputBuilder.BootStrap();
ConfigureAutoMapper();
}
public static void ConfigureAutoMapper()
{
Mapper.CreateMap<User, UserDisplay>()
.ForMember(o => o.UserRolesDescription,
opt => opt.ResolveUsing<RoleValueResolver>());
Mapper.CreateMap<Organisation, OrganisationDisplay>();
Mapper.CreateMap<Organisation, OrganisationOpenDisplay>();
Mapper.CreateMap<OrganisationAddress, OrganisationAddressDisplay>();
}
}
Run Code Online (Sandbox Code Playgroud)
mry*_*ren 39
我认为你违反了两个原则:单一责任原则(SRP)和开放/封闭原则(OCP).
您违反了SRP,因为bootstrapping类有多个原因需要更改:如果您更改模型绑定或自动映射器配置.
如果要添加其他引导代码以配置系统的另一个子组件,则会违反OCP.
我通常如何处理这个是我定义以下界面.
public interface IGlobalConfiguration
{
void Configure();
}
Run Code Online (Sandbox Code Playgroud)
对于系统中需要引导的每个组件,我将创建一个实现该接口的类.
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.
}
}
Run Code Online (Sandbox Code Playgroud)
我使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我将以下代码添加到Global.asax文件中.
public class MvcApplication : HttpApplication
{
public void Application_Start()
{
IKernel kernel = new StandardKernel(
new AutoMapperModule(),
new MvcModule(),
new GlobalConfigurationModule()
);
Kernel.Get<IGlobalConfiguration>().Configure();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的引导代码遵循SRP和OCP.我可以通过创建实现IGlobalConfiguration
接口的类来轻松添加其他引导代码,而我的全局配置类只有一个原因需要更改.