Here is the component for which I want to configure mapping
public class Range<T> : ValueObject
{
public virtual T Start {get; set;}
public virtual T Finish {get; set;}
}
In my domain I have many entities which have properties like Range < DateTime>, Range < int > ... for a particular class with property x we configure the component this way:
persistenceModel.FindMapping<Customer>()
.Component<Address> (
x => x.CustomerAddress,
m =>
{
m.Map(x => x.Street).WithLengthOf(100);
m.Map(x => x.PostalCode).WithLengthOf(6);
m.Map(x => x.Town).WithLengthOf(30);
m.Map(x => x.Country).WithLengthOf(50);
});
How looks the convention for whole domain as generic T ? Do I miss something. Is not possible with FluentNhibernate ?
You should not be using FindMapping
for that purpose. Being able to alter the mappings through that method is an oversight, and should definitely not be relied upon. That method is for inspecting the persistence model, not altering it. If you're using automapping, you should look into overrides.
I believe your problem could be solved with an ICompositeUserType
implementation; there are several resources available online on how to implement these, specifically a generic composite user type implementation. You'd just map your range property as normal, but supply the user type to it using CustomType
.
Map(x => x.Range)
.CustomType<RangeUserType>();
You could also do it with the newly introduced ComponentMap
functionality, but it doesn't support mapping open generic types without the use of base-classes.
Something like this would probably work:
public abstract class RangeMap<T> : ComponentMap<T>
{
protected RangeMap()
{
Map(x => x.Start);
Map(x => x.Finish):
}
}
public class IntRangeMap : RangeMap<int>
{}
public class DateRangeMap : RangeMap<DateTime>
{}
Admittedly, it's not ideal.