Как автоматизировать коллекцию компонентов с помощью Fluent NHibernate? - PullRequest
6 голосов
/ 27 января 2011

Все мои сущности и объекты-значения реализуют интерфейсы маркеров IEntity и IValueObject.Я настроил их так, чтобы они обрабатывались как компоненты:

public override bool IsComponent(Type type)
{
    return typeof(IValueObject).IsAssignableFrom(type);
}

public override bool ShouldMap(Type type)
{
    return typeof(IEntity).IsAssignableFrom(type) || typeof(IValueObject).IsAssignableFrom(type);
}

К сожалению, это, похоже, не позволяет автоматически создавать сущности, у которых есть коллекции объектов-значений, как коллекции компонентов.Например:

public class MyEntity : IEntity
{
    public IList<MyValueObject> Objects { get; set; }
}

public class MyValueObject : IValueObject
{
    public string Name { get; set; }
    public string Value { get; set; }
}

Есть ли способ определить соглашение таким образом, чтобы в любое время IEntity имел IList типа, который реализует IValueObject, он отображался, как если бы я имелуказано:

HasMany(x => x.Objects)
    .Component(x => { 
        x.Map(m => m.Name); 
        x.Map(m => m.Value); 
    });

Чего я не хочу, так это вручную делать эти переопределения для каждого класса и снова и снова записывать каждое свойство для объекта значения.

1 Ответ

1 голос
/ 14 ноября 2011
  1. Создайте новый класс, который наследуется от HasManyStep (FluentNHibernate.Automapping.Steps).
  2. Переопределите метод ShouldMap () с помощью чего-то вроде:

    return base.ShouldMap(member) && IsCollectionOfComponents(member)
    
  3. Добавьте свою логику в:

    public void Map(ClassMappingBase classMap, Member member)
    { ... }
    
  4. Замените шаг по умолчанию на новый:

    public class MyMappingConfiguration : DefaultAutomappingConfiguration
    {
        public override IEnumerable<IAutomappingStep> GetMappingSteps(AutoMapper mapper, IConventionFinder conventionFinder)
        {
            var steps = base.GetMappingSteps(mapper, conventionFinder);
            var finalSteps = steps.Where(c => c.GetType() != typeof(FluentNHibernate.Automapping.Steps.HasManyToManyStep)).ToList();
            var idx = finalSteps.IndexOf(steps.Where(c => c.GetType() == typeof(PropertyStep)).First());
            finalSteps.Insert(idx + 1, new MyCustomHasManyStep(this));
            return finalSteps; 
        }
    }
    

Примечание. Вы также можете получить исходный код файла HasManyStep.cs и скопировать его в свой проект, чтобы представить свою пользовательскую логику.

...