6

Tutte le entità e gli oggetti valore implementano le interfacce marker IEntity e IValueObject. Li ho impostato per essere trattati come componenti in questo modo:Come automatizzare una raccolta di componenti con Fluent NHibernate?

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

Purtroppo, questo non sembra per consentire alle imprese che dispongono di collezioni di oggetti di valore da automapped come le collezioni dei componenti. Ad esempio:

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

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

Esiste un modo per definire una convenzione tale che, ogni volta che un IEntity ha un IList di un tipo che implementa IValueObject, esso viene mappato come se fossi specificato:

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

Quello che non voglio fare è di avere a che fare manualmente queste sostituzioni per ogni classe e scrivere ogni proprietà per l'oggetto valore di nuovo e di nuovo.

risposta

0
  1. creare una nuova classe che eredita da HasManyStep (FluentNHibernate.Automapping.Steps).
  2. sovrascrivere il metodo ShouldMap() con qualcosa come:

    return base.ShouldMap(member) && IsCollectionOfComponents(member) 
    
  3. Aggiungi la tua logica per:

    public void Map(ClassMappingBase classMap, Member member) 
    { ... } 
    
  4. Sostituire il passo predefinito con quello nuovo:

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

Nota: è anche possibile ottenere il codice sorgente originale di HasManyStep.cs e copiarlo nel progetto per introdurre la logica personalizzata.