How to automate component assembly using Fluent NHibernate?

All of my objects and value objects implement the IEntity and IValueObject marker interfaces. I set them so that they are considered as components:

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

Unfortunately, this, apparently, does not allow entities that have collections of value objects to be automatically deleted as collections of components. For example:

 public class MyEntity : IEntity { public IList<MyValueObject> Objects { get; set; } } public class MyValueObject : IValueObject { public string Name { get; set; } public string Value { get; set; } } 

Is there a way to define a convention so that at any time when IEntity has an IList type that implements IValueObject , it displays as if I pointed out:

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

What I do not want to do is manually perform these overrides for each class and write out each property for the value object again and again.

+6
nhibernate components fluent-nhibernate automapping value-objects
source share
1 answer
  • Create a new class that inherits from HasManyStep (FluentNHibernate.Automapping.Steps).
  • Override the ShouldMap () method with something like:

     return base.ShouldMap(member) && IsCollectionOfComponents(member) 
  • Add your logic to:

     public void Map(ClassMappingBase classMap, Member member) { ... } 
  • Replace the default step with a new one:

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

Note. You can also get the source code of HasManyStep.cs and copy it into your project to present your own logic.

0
source share

All Articles