Свободный Nhibernate - ClassMaps в нескольких отдельных сборках - PullRequest
1 голос
/ 09 октября 2011

Рассмотрим следующую Свободную конфигурацию;

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, так что любое решение, которое я хочу создать, может мгновенно получить мои стандартизированные возможности членства, а также возможность просто создать его собственные решения для ClassMaps и добавить их в объект конфигурации.

Проблема в том, что знакомый вызов;

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

только кажется, что может справиться с одной сборкой. Неважно, что добавлено в список, будет отображена только последняя добавленная сборка. В качестве альтернативы вышесказанному я пытался удерживать ссылку на MappingConfiguration (что означает «m» в config.Mappings(m => )), но это тоже не сработало. Очевидно, что такой вызов m.FluentMappings.AddFromAssembly или любого другого метода FluentMappings.Add перезапишет то, что было ранее, но наверняка есть способ сделать это? Это не так уж и странно.

1 Ответ

1 голос
/ 20 сентября 2013

Старый вопрос, но мне удалось решить его, посмотрев на него, поэтому я постараюсь ответить на него. Вот как я это сделал (.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, это из тестового проекта):

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();
...