Fluent nhibernate 如何在FluentNhibernate AutoPersistenceModel generator中使用来自多个程序集的映射重写

Fluent nhibernate 如何在FluentNhibernate AutoPersistenceModel generator中使用来自多个程序集的映射重写,fluent-nhibernate,Fluent Nhibernate,是否可以将autopersistence模型配置为从多个程序集读取映射和映射重写 目前我使用 public AutoPersistenceModel Generate() { var model = new AutoPersistenceModel() .AddEntityAssembly(Assembly.GetAssembly(typeof(User)))

是否可以将autopersistence模型配置为从多个程序集读取映射和映射重写

目前我使用

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;
        }
public AutoPersistenceModel Generate()
{
var模型=
新的AutoPersistenceModel()
.AddEntityAssembly(Assembly.GetAssembly(typeof(User)))
.在哪里(
this.GetAutoMappingFilter).Conventions.Setup(this.GetConventions()).Setup(this.GetSetup())。
使用OverridesFromAssemblyof();
收益模型;
}
公共AutoPersistenceModel生成(参数程序集[]程序集)
{
var model=this.Generate();
assemblies.ToList().ForEach(x=>model.AddEntityAssembly(x));
收益模型;
}
问题在于

  UseOverridesFromAssemblyOf<AutoPersistenceModelGenerator>();
UseOverridesFromAssemblyOf();
它只需要一个程序集。但我想从不同的集合中收集地图和其他工具


谢谢

因此.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代码之后,我发现他们最终改变了AutomappingGoverrideControlation,我只是写了一个扩展来应用这个改变

 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);
        }


    }

baseMappings.dll包含我们的基本实体,如:用户、查找等。因此,它可以是任何包含基本、默认映射、约定等的程序集。

我们使用FNH的1.3.x版本采用了稍微不同的方法来解决此问题,同时考虑到一些特定的设计目标:

  • 保持我们的域实体POCO
  • 利用FNH自动持久化机制
  • 包IAutoMappingOverride程序集中的实例及其所依赖的图元
  • 允许包含映射实体的新程序集的“插件”,而无需更改核心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<>));
    }
}
内部密封类会话配置:DefaultAutomappingConfiguration
{
公共自动持久性模型持久性模型
{
得到
{
Assembly[]assembliesToMap=MappedAssemblyResolver.GetMappedAssemblies();
AutoPersistenceModel model=AutoMap.Assemblies(新SessionConfiguration(),assembliesToMap);
foreach(可能映射到MappedAssemblyResolver.GetOverrideAssembly(assembliesToMap)中的程序集)
{
model.UseOverridesFromAssembly(潜在映射);
}
model.Conventions.AddFromAssemblyOf();
//省略了其他FNH配置选项
收益模型;
}
}
公共覆盖布尔ShouldMap(类型)
{
返回类型.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;
    }
}
内部静态类MappedAssemblyResolver
{
公共静态程序集[]GetMappedAssemblies()
{
装配和装配;
//TODO:实施解决程序集的策略
返回地图踏板组件;
}
公共静态IEnumerable
  • CheckNullOrEmpty(string)是一个扩展方法,可用
  • <> LI>您需要实现一种实际解决GETMaFabdDebug()中的程序集的方法。我们对AppDima.Currand域进行一些检查,并应用一些规则来确定我们认为哪些程序集是匹配的。 还请注意,当我们将IAutoMappingOverride实例与实体放在同一个程序集中时,如果您的目标是进一步将域与FNH解耦,那么您可以轻松地更改GetOverrideAssembly(assembly[])的实现


    无论哪种方式,都应允许您添加新的映射实体(或包含它们的新程序集)它们的相关映射随意覆盖,而不考虑它们添加到底层FNH AutoPersistenceModel中。

    谢谢,首先看看这个想法对我来说很好。只需要检查重构对这方面的影响,应该不会太大。
    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<>));
        }
    }
    
    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;
        }
    }