是否可以配置自动存在模型以从多个程序集中读取映射和映射覆盖。
目前我使用
public AutoPersistenceModel Generate()
{
var model =
new AutoPersistenceModel()
.AddEntityAssembly(Assembly.GetAssembly(typeof(User)))
.Where(
this.GetAutoMappingFilter).Conventions.Setup(this.GetConventions()).Setup(this.GetSetup()).
UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();
return model;
}
public AutoPersistenceModel Generate(params Assembly[] assemblies)
{
var model = this.Generate();
assemblies.ToList().ForEach(x => model.AddEntityAssembly(x));
return model;
}
问题在于
UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();
只需一个程序集。 BUt我想从不同的程序集中收集映射和它们的其他内容。
由于
答案 0 :(得分:2)
我们采用了一种略微不同的方法来解决这个问题,使用1.3.x版本的FNH,并考虑到一些特定的设计目标:
与OP的解决方案非常相似,我们所有的映射实体都从一组众所周知的基类继承。有了这个以及可以确实多次调用AutoPersistenceModel.UseOverridesFromAssembly()的事实,我们能够对我们的自动映射配置类进行简单的修改,以动态添加覆盖程序集:
internal sealed class SessionConfiguration : DefaultAutomappingConfiguration
{
public AutoPersistenceModel PersistenceModel
{
get
{
Assembly[] assembliesToMap = MappedAssemblyResolver.GetMappedAssemblies();
AutoPersistenceModel model = AutoMap.Assemblies(new SessionConfiguration(), assembliesToMap);
foreach (Assembly potentiallyMapped in MappedAssemblyResolver.GetOverrideAssemblies(assembliesToMap))
{
model.UseOverridesFromAssembly(potentiallyMapped);
}
model.Conventions.AddFromAssemblyOf<SessionConfiguration>();
// other FNH configuration options omitted
return model;
}
}
public override bool ShouldMap(Type type)
{
return type.IsSubclassOfRawGeneric(typeof(DomainObject<>));
}
}
MappedAssemblyResolver看起来像这样:
internal static class MappedAssemblyResolver
{
public static Assembly[] GetMappedAssemblies()
{
Assembly[] mappedAssemblies;
// TODO: implement your strategy for resolving assemblies
return mappedAssemblies;
}
public static IEnumerable<Assembly> GetOverrideAssemblies(Assembly[] mappedAssemblies)
{
mappedAssemblies.CheckNull("mappedAssemblies");
return mappedAssemblies;
}
}
一些注意事项:
另请注意,虽然我们将IAutoMappingOverride实例放在与实体相同的程序集中,但如果您的目标是进一步将域与FNH分离,则可以轻松更改GetOverrideAssemblies(Assembly [])的实现。
无论哪种方式,这应该允许您随意添加新的映射实体(或包含它们的新程序集)及其相关的映射覆盖,而不必过多考虑它们对底层FNH AutoPersistenceModel的添加。
答案 1 :(得分:1)
因此.UseOverridesFromAssemblyOf的问题是它们不会重复类型。
从FluentNHibernate剪下的代码:
public AutoPersistenceModel UseOverridesFromAssembly(Assembly assembly)
{
this.alterations.Add(new AutoMappingOverrideAlteration(assembly));
return this;
}
public AutoMappingAlterationCollection Add(IAutoMappingAlteration alteration)
{
if (!this.alterations.Exists(a => a.GetType() == alteration.GetType()))
{
this.alterations.Add(alteration);
}
return this;
}
您可以看到不允许添加重复类型。
在调查FNH代码后,我发现他们最终改变了AutoMappingOverrideAlteration,我只是写了一个扩展来应用这个改变
public static class AutoPersistenceModelExtension
{
public static AutoPersistenceModel AddMappingAssembly(this AutoPersistenceModel model, Assembly assembly)
{
new AutoMappingOverrideAlteration(assembly).Alter(model);
return model;
}
public static AutoPersistenceModel AddMappingFromAssemblyOf<T>(this AutoPersistenceModel model)
{
return model.AddEntityAssembly(typeof (T).Assembly);
}
}
结果是: 我们的应用程序是基于组件构建的,每个组件为这些实体提供自己的实体和映射。每个组件都应该从BaseComponent类派生,该类具有改变模型的抽象方法。
Exof FulfillmentModuleRegistration:
public override void AddToModel(AutoPersistenceModel autoPersistenceModel)
{
autoPersistenceModel.AddEntityAssembly(typeof(SupplierListItem).Assembly);
autoPersistenceModel.AddMappingFromAssemblyOf<SupplierListItemMappingOverride>();
}
和我们的global.asax.cs:
var autoPersistenceModel = new AutoPersistenceModelGenerator().Generate();
//TODO: Refactor this, instead of instantiate each module we have to go thought a list of loaded module and apply their model alteration
new QuestionBankModuleRegistration().AddToModel(autoPersistenceModel);
new FulfilmentServiceAreaRegistration().AddToModel(autoPersistenceModel);
var cfg = NHibernateSession.Init(
this.webSessionStorage,
new[] { this.Server.MapPath("~/bin/baseMappings.dll") },
autoPersistenceModel,
this.Server.MapPath("~/Hibernate.cfg.xml"));
baseMappings.dll包含我们的基本实体,例如:Users,Lookups等。因此它可以是包含基本,默认映射,约定等的任何程序集。