我认为你违反了两个原则:单一责任原则(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
接口的类轻松地添加额外的引导代码,而我的全局配置类只有一个理由需要更改。
,而且您仍然必须更改Configure方法在AutoMapperGlobalConfiguration中每次需要添加一个新的映射时 – Omu 2009-11-28 06:27:43
但是这不会违反OCP。 OCP不写入一次再也不会触摸。 OCP指出引导代码的使用者GlobalConfigurationModule(GCM)应该依赖于抽象而不是实现。如果我要为log4net添加引导,我将创建一个类Log4NetGlobalConfiguration类来实现IGlobalConfiguration。然而,我不需要修改我的代码的任何其他部分,也不必修改GCM,因为它没有关于IGlobalConfiguration接口的conrete实现的复杂知识。 – mrydengren 2009-11-28 07:36:07
我有疑问。一旦执行Mapper.CreateMap <>(),映射就会存在,直到应用程序关闭? – JPCF 2011-01-03 22:56:06