У меня сегодня работает, но не красиво.Это также не использует соглашение.Как я понимаю соглашения, они действительно предназначены для настройки вещей после того, как произошло основное сопоставление.Я полагаю, что добавление отображений не входит в сферу действия соглашений.
В моем проекте у меня есть общая процедура инициализации, основанная на автоматическом сопоставлении, которая ничего не знает о типах, но имеет переопределенные сопоставления для составных ключей.Не совсем твой сценарий, но это похожая проблема.
Способ, которым я заставил это работать через отражение, заключался в том, чтобы заполучить соответствующий объект AutoPersistenceModel.Если у вас есть код, похожий на этот:
Fluently.Configure().Mappings(m => ...
Объектом AutoPersistenceModel будет m.AutoMappings.First ()
Отсюда это довольно серьезная работа по отражению, завершающаяся вызовомзащищенный метод внутри FluentNHibernate.Вот код, который я использую:
private void Override(AutoPersistenceModel container,
Type type,
IEnumerable<KeyValuePair<string,string>> compositeKeys)
{
// We need to call container.Override<T>(Action<Automapping<T>> populateMap)
// Through reflection...yikes
var overrideMethod = typeof(AutoPersistenceModel)
.GetMethod("Override")
.MakeGenericMethod(type);
var actionFactoryMethod = typeof(FluentNHibernateInitializer)
.GetMethod("CompositeMapperFactory",
BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(type);
var actionMethod = actionFactoryMethod
.Invoke(this, new object[] { compositeKeys });
overrideMethod.Invoke(container, new object[] {actionMethod});
}
private Action<AutoMapping<T>> CompositeMapperFactory<T>
(IEnumerable<KeyValuePair<string, string>> compositeKeys)
{
return new Action<AutoMapping<T>>(m =>
{
var compositeId = m.CompositeId();
foreach (var kvp in compositeKeys)
compositeId =
AddKeyProperty(
compositeId,
typeof(T).GetProperty(kvp.Key),
kvp.Value);
}
);
}
/// <summary>
/// Uses reflection to invoke private and protected members!
/// </summary>
/// <param name="compositeId"></param>
/// <param name="propertyInfo"></param>
/// <returns></returns>
private CompositeIdentityPart<T> AddKeyProperty<T>
(CompositeIdentityPart<T> compositeId,
PropertyInfo propertyInfo,
string column)
{
var member = FluentNHibernate.MemberExtensions.ToMember(propertyInfo);
var keyPropertyMethod = typeof(CompositeIdentityPart<T>)
.GetMethod("KeyProperty",
BindingFlags.Instance | BindingFlags.NonPublic);
return (CompositeIdentityPart<T>)
keyPropertyMethod
.Invoke(compositeId, new object[] { member, column, null });
}