Здравствуйте.
Посоветуйте, как бы вы решали такую проблему.
Есть сущность (с наследниками)
public interface IClonable<T> where T:...
{
T Clone();
}
public class CostInfo: ..., IClonable<CostInfo>
{
...
protected virtual CostInfo newInstance()
{
return new CostInfo(...);
}
public CostInfo Clone()
{
var ci = newInstance();
//set props
return ci;
}
}
public class OtherCostInfo: ..., IClonable<OtherCostInfo>
{
...
protected override OtherCostInfo newInstance()
{
return new OtherCostInfo(...);
}
public new OtherCostInfo Clone()
{
var ci = (OtherCostInfo)base.Clone();
//set OtherCostInfo specific props
return ci;
}
}
Так уж вышло, что эти сущности хранятся в другой сущности. Причем коллекция может содержать в некоторых случаях CostInfo, в других OtherCostInfo (либо либо, вместе не хранятся).
public class SomeCostHolder
{
public IList<CostInfo> Costs { get { ... } }
}
Потребовался функционал для копирования SomeCostHolder. Среди прочего кода появился хелпер:
//псевдокод
public void CopyCollection<T>(IList<T> source, IList<T> target, ...) where T: IClonable<T>
{
source.ForEach(si => target.Add(si.Clone()));
}
И тут выяснилось, что бывают ситуации, когда при копировании надо конвертировать CostInfo в OtherCostInfo, т.к. другой SomeCostHolder, в который копируются данные, не ожидает у себя в коллекции CostInfo. Проблема у меня тут в том, что метод Clone специально добавлен в DomainModel, что-бы быть поближе к копируемым данным и не забывать его обновлять при изменении модели. А теперь ситуация вынуждает превратить копирование (клонирование) в конвертирование. Для задачи достаточно скопировать только то, что может быть скопировано (от общих предков). Специальная логика конвертации не требуется. При этом не хочется вводит связность в модель (разные наследники знают друг о друге) и не хочется тащить все это вовне в отдельный класс (будем забывать обновлять его). Вводить m:m конвертеров по кол-ву возможных сочетаний как то тоже гм.
Свое решение приводить не буду (пока), хочется посмотреть на возможные подходы.
зы: а то три года времени не было толком на форуме посидеть, а тут как почитал, сколько копий сломано в Anemic vs Rich, так сразу сомнения появляются в квалификации
ззы: высказывания по типу SomeCostHolder криво спроектирован тоже принимаются, но с примером, как надо было спроектировать