流利的Nhibernate - ClassMaps在多个独立的组件中

时间:2011-10-09 14:31:57

标签: nhibernate fluent-nhibernate mapping

考虑以下 Fluent 配置;

FluentConfiguration config = Fluently.Configure();
        config.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008.ConnectionString(ConfigurationManager.ConnectionStrings[dbKey].ConnectionString));

        // MemberMap is in the same assembly as this class, contains
        // maps for member and role entities as part of a default
        // membership service provider
        MappingAssemblies.Add(typeof(MemberMap).Assembly);

        foreach (Assembly mappingAssembly in MappingAssemblies)
        {
            // For each assembly that has been added to MappingAssemblies
            // we add to the current mapping configuration.  This allows
            // me to drop this helper into any solution and it provide 
            // standardized membership abilities AS WELL AS manage
            // the solutions unique ClassMaps 
            config.Mappings(m => 
                m.FluentMappings.AddFromAssembly(mappingAssembly)
                );
        }

        if (exportSchema)
        {
            config.ExposeConfiguration(cfg =>
                    {
                        new SchemaExport(cfg)
                        .Create(true, true);
                    }
                );
        }

        _sessionFactory = config.BuildSessionFactory();

这个逻辑保存在我在应用程序启动时从Global.asax中调用的静态类中。启动配置看起来类似于;

Database.MappingAssemblies.Add(typeof(PageContentMap).Assembly);
// This is the method detailed above
Database.FluentConfigureSessionFactory("MySolutionsDb", true);

所以我的想法是我将我的Member和Role实体对象打包到与Database helper对象相同的程序集中,这样我想要创建的任何解决方案都可以立即获得我的标准化成员资格能力,并且能够简单地创建它拥有解决方案特定的ClassMaps并将它们添加到配置对象。

问题是,熟悉的呼叫;

config.Mappings(m => 
                m.FluentMappings.AddFromAssembly(mappingAssembly)
                );

似乎只能处理单个程序集。无关紧要添加到列表中的内容,只会映射添加的最后一个程序集。作为上述内容的替代方案,我尝试持有对MappingConfiguration的引用(这是'{'代表config.Mappings(m => )中的内容),但这也不起作用。很明显,对m.FluentMappings.AddFromAssembly或任何FluentMappings.Add方法的调用都会覆盖以前的方法,但肯定有办法完成这项工作吗?它看起来并不像是一个“怪异”的要求。

1 个答案:

答案 0 :(得分:1)

老问题,但我看了之后设法解决了,所以我会尝试回答它。这就是我做的(.ForEach()是NHibernate.Linq的扩展):

config.Mappings(m => MappingAssemblies.ForEach(a => m.FluentMappings.AddFromAssembly(a)))

我必须为自动映射的东西做这件事,并且语法有点不同。我有一个界面,标记我想要自动化的所有类:

config.Mappings(m => 
    m.AutoMappings.Add(AutoMap.Assemblies(MappingAssemblies.ToArray())
    .Where(x => x.GetInterfaces().Contains(typeof(IAutoMappedEntity)))))

另外,我没有手动设置的“MappingAssemblies”,我采用了包含所有程序集的懒惰方法,所以我的配置看起来像这样(使用SQLite,这是来自测试项目):< / p>

var MappingAssemblies = AppDomain.CurrentDomain.GetAssemblies()
    .Where(a => a.FullName.StartsWith("MyCompanyName."));
Configuration configuration;

var sessionFactory = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory())
     // This adds fluent mappings
    .Mappings(m => MappingAssemblies.ForEach(a => m.FluentMappings.AddFromAssembly(a)))
     // This adds automapped classes using specific configuration
    .Mappings(m => m.AutoMappings.Add(AutoMap.Assemblies(new MyAutomapConfiguration(), MappingAssemblies)))
     // This adds automapped classes that just use my magic interface
    .Mappings(m => m.AutoMappings.Add(AutoMap.Assemblies(MappingAssemblies.ToArray()).Where(x => x.GetInterfaces().Contains(typeof(IAutoMappedEntity)))))
    .ExposeConfiguration(cfg => configuration = cfg)
    .BuildSessionFactory();