2010-04-13 1 views
5

, 나는 다음과 같은 코드를 작성했습니다 fluentnhibernate automapper에서 인터페이스에 대한 AutoMappingOverride을 제공하는 가장 좋은 방법입니다 인터페이스에서 작동하지 않는, 나는 이것을 구현하는 방법을 찾고있다. 현재 나는 인터페이스를 구현하는 각 클래스에 대한이 (오히려 성가신) 방법을 사용하고 있습니다 : 나는 등 IClassmap 인터페이스에서 찾고있다는 어떤 응용 프로그램에 대한 버전 전체 데이터베이스 필터에 대한 나의 탐구에

public class SomeVersionedEntity : IModelId, IVersionAware 
{ 
    public virtual int Id { get; set; } 
    public virtual string Version { get; set; } 
} 

public class SomeVersionedEntityOverride : IAutoMappingOverride<SomeVersionedEntity> 
{ 
    #region IAutoMappingOverride<SomeVersionedEntity> Members 

    public void Override(AutoMapping<SomeVersionedEntity> mapping) 
    { 
     mapping.ApplyFilter<VersionFilter>(); 
    } 

    #endregion 
} 

을하지만, 그들은으로 applyFilter 방법에 액세스 할 수있는 방법을 제공하지 않는 것 그래서 여기에 단서가 없습니다 ...

저는이 문제가있는 사람이 처음이 아니기 때문에 가능해야한다고 확신합니다. 나는 이것이 어떻게 작동하는지 다만 아주 잘 모르겠습니다 ..

편집 : 사용

:

이 내가 그것을 해결하기 위해 시도한 방법이다 : 나는 일반적인 솔루션에 조금 더 가까이 입수했습니다

public abstract class AutomappingInterfaceAlteration<I> : IAutoMappingAlteration 
{ 
    public void Alter(AutoPersistenceModel model) 
    { 
     model.OverrideAll(map => 
     { 
      var recordType = map.GetType().GetGenericArguments().Single(); 
      if (typeof(I).IsAssignableFrom(recordType)) 
      { 
       this.GetType().GetMethod("overrideStuff").MakeGenericMethod(recordType).Invoke(this, new object[] { model }); 
      } 
     }); 
    } 

    public void overrideStuff<T>(AutoPersistenceModel pm) where T : I 
    { 
     pm.Override<T>(a => Override(a)); 
    } 

    public abstract void Override<T>(AutoMapping<T> am) where T:I; 
} 

그리고 특정 구현 :

제네릭 클래스는 인터페이스를 구현하는 클래스에 변경을 구현하는
public class VersionAwareAlteration : AutomappingInterfaceAlteration<IVersionAware> 
{ 
    public override void Override<T>(AutoMapping<T> am) 
    { 
     am.Map(x => x.Version).Column("VersionTest"); 
     am.ApplyFilter<VersionFilter>(); 
    } 
} 

불행하게도 지금은 다음과 같은 오류가 발생합니다 :

[InvalidOperationException: Collection was modified; enumeration operation may not execute.] 
    System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) +51 
    System.Collections.Generic.Enumerator.MoveNextRare() +7661017 
    System.Collections.Generic.Enumerator.MoveNext() +61 
    System.Linq.WhereListIterator`1.MoveNext() +156 
    FluentNHibernate.Utils.CollectionExtensions.Each(IEnumerable`1 enumerable, Action`1 each) +239 
    FluentNHibernate.Automapping.AutoMapper.ApplyOverrides(Type classType, IList`1 mappedProperties, ClassMappingBase mapping) +345 
    FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedProperties) +43 
    FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types) +566 
    FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type) +85 
    FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings() +746 

편집 2 : 나는 조금 더를 얻을 수 있었다; 이유 중 하나 또는 다른 내 생성 된 "필터"필드를 포함하지 않는 HBM 파일 .... 어쩌면 누군가, 그러나

public abstract class PersistenceOverride<I> 
{ 

    public void DoOverrides(AutoPersistenceModel model,IEnumerable<Type> Mytypes) 
    { 
     foreach(var t in Mytypes.Where(x=>typeof(I).IsAssignableFrom(x))) 
      ManualOverride(t,model); 
    } 

    private void ManualOverride(Type recordType,AutoPersistenceModel model) 
    { 
     var t_amt = typeof(AutoMapping<>).MakeGenericType(recordType); 
     var t_act = typeof(Action<>).MakeGenericType(t_amt); 
     var m = typeof(PersistenceOverride<I>) 
       .GetMethod("MyOverride") 
       .MakeGenericMethod(recordType) 
       .Invoke(this, null); 
     model.GetType().GetMethod("Override").MakeGenericMethod(recordType).Invoke(model, new object[] { m }); 
    } 

    public abstract Action<AutoMapping<T>> MyOverride<T>() where T:I; 
} 

public class VersionAwareOverride : PersistenceOverride<IVersionAware> 
{ 
    public override Action<AutoMapping<T>> MyOverride<T>() 
    { 
     return am => 
     { 
      am.Map(x => x.Version).Column(VersionFilter.COLUMNNAME); 
      am.ApplyFilter<VersionFilter>(); 
     }; 
    } 
} 

: 지금 인터페이스를 구현하는 각 클래스에 대한 반사를 사용하여 "재정의"호출 나 좀 더 지금 도울 수 있을까 ??

답변

1

유창한 nhibernate의 현재 버전에는 분명히 버그가있었습니다. Automapper.Override를 사용하면 필터가 복사되지 않았습니다. <T>.

나는 소스를 포크하고, 버그를 수정하고, 테스트를 마쳤으며, 지금은 github에서 fluentnhib 친구들에게 풀 요청을 보냈습니다. http://www.corebvba.be/blog/post/How-to-override-interface-mappings-and-creata-a-generic-entity-version-filter-in-fluent-nhibernate.aspx

:

은 지금, 당신은이 작업을 수행하는 방법에 대한 완전한 블로그 게시물도 지금이 http://github.com/ToJans/fluent-nhibernate/commit/29058de9b2bc3af85bc433aa6f71549f7b5d8e04

에 고정 된 소스 코드를 다운로드 할 수 있습니다