Здравствуйте, IT, Вы писали:
O>> Неудобно только то, что всем out параметрам нужно будет явно присваивать значение в реализации GetFieldstring fieldName, out object value).
IT>Да уж, как-то это всё не очень...
Не очень
out? Его можно поменять на
ref 
Или сама идея вызывать IMapGettable.GetField в MapDescriptor.GetFieldValue плоха?
Можно переделать с
ref как
object IMapDataSource.GetFieldValue(string name, object entity)
{
IMemberMapper mm = this[name];
object value = mm != null ? mm.GetValue(entity) : null;
IMapGettable mg;
if ((mg = entity as IMapGettable) != null && value != null)
{
mg.GetField(name, ref value);
}
return value;
}
Тогда IMapGettable.GetField если захочет — изменит значение value. Ну а если нет — то нет.
IT>Я бы глянул в сторону конструктора с MapInitializeData параметром. Он перед маппингом получает в это структуре все необходимые данные.
Это в смысле Map.MapInternal? Но там проверку на реализацию IMapGettable прийдется делать в двух местах:
Map.MapInternal(
IMapDataSource source,
object sourceData,
IMapDataReceiver receiver,
object receiverData,
MapInitializingData data)
{
if (receiverData is ISupportInitialize)
((ISupportInitialize)receiverData).BeginInit();
// реализует ли sourceData IMapGettable
IMapGettable mg = sourceData as IMapGettable;
if (receiverData is IMapSettable)
{
IMapSettable mapReceiver = (IMapSettable)receiverData;
for (int i = 0; i < source.FieldCount; i++)
{
string name = source.GetFieldName(i);
object o = source.GetFieldValue(i, sourceData);
// проверка №1
if (mg != null)
{
// скажем для какого поля будет подставлено значение
mg.GetField(name, ref o);
}
MapDescriptor md = data.MapDescriptor;
if (mapReceiver.SetField(name, o) == false)
{
int idx = receiver.GetOrdinal(name);
if (idx >= 0)
{
receiver.SetFieldValue(idx, name, receiverData, o);
}
}
}
}
else
{
for (int i = 0; i < source.FieldCount; i++)
{
string name = source.GetFieldName(i);
// -----------------------------------
if (name.Length > 0)
{
int idx = receiver.GetOrdinal(name);
if (idx >= 0)
{
object o = source.GetFieldValue(i, sourceData);
// проверка №2
if (mg != null)
{
// скажем для какого поля будет подставлено значение
mg.GetField(name, ref o);
}
receiver.SetFieldValue(idx, name, receiverData, o);
}
}
}
}
if (receiverData is ISupportInitialize)
((ISupportInitialize)receiverData).EndInit();
}
... << RSDN@Home 1.1.4 beta 3 rev. 185>>