2011-10-09 2 views
1

다음을 고려하십시오. Fluent 구성;Fluent Nhibernate - 여러 개의 개별 어셈블리에있는 클래스 맵

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

그래서 생각이 내 회원 및 역할 엔티티가 데이터베이스 도우미 개체와 같은 어셈블리에 객체를 포장 한 것입니다 그래서 내가 할 수있는뿐만 아니라 즉시 내 표준화 된 회원의 능력을 얻을 수 있습니다 만들 신경 모든 솔루션 고유 한 솔루션 별 ClassMaps를 만들어 구성 객체에 추가하면됩니다.

문제는 친숙한 호출입니다.

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

은 단일 어셈블리를 처리 할 수있는 것 같습니다. 목록에 무엇이 추가되는지는 중요하지 않으며 추가 된 마지막 어셈블리 만 매핑됩니다. 위의 대안으로, 나는 MappingConfiguration (이것은 'config.Mappings(m =>)'에 'm'이 표시되어 있음)에 대한 참조를 보유하려고 시도했지만 이것도 작동하지 않았습니다. m.FluentMappings.AddFromAssembly 또는 실제로 FluentMappings.Add 메서드 중 하나를 호출하면 이전에 있던 내용을 덮어 쓰 겠지만 확실하게이 작업을 수행 할 수있는 방법이 있습니까? 그것은 그다지 이상한 요구 사항이 아닌 것 같습니다.

+0

단지 궁금한데 왜 다른 어셈블리에 하나의 데이터베이스와 관련된 엔티티를 저장하고 있습니까? 이것이 유효한 질문은 아니지만 또 다시 호기심이있는 것은 아닙니다. –

+0

FNH의 어떤 버전을 사용하십니까? 많은 매핑 어셈블리에 대한 버그/제한이 있었음을 기억합니다. – Firo

+0

@Cole W. 그래서 Member 및 Role 엔티티 객체는 정적 데이터베이스 클래스와 동일한 어셈블리에서 왔지만 여전히 .AddAssemblyOf () 호출이 필요합니다. 그렇다면 이것은 .dll로 패키징되어 새로운 솔루션으로 참조됩니다. Member 및 Role 객체를 새 솔루션 데이터베이스에 매핑하기 위해 .AddAssemblyOf ()을 호출하는 동안이 새로운 솔루션과 관련된 고유 한 엔티티 객체도 매핑해야합니다. 앞에서 언급 한 Member 및 Role 객체의 동일한 어셈블리에 포함되지 않습니다. – user407356

답변

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"을 필요는 없습니다, 나는, 단지 내 모든 어셈블리를 포함하는 게으른 착수했습니다 그래서 내 config는 다음과 같습니다 (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(); 
관련 문제