Huh, temat zawiły.
Więc tak. Mam sobie jakąś hierarchię dziedziczenia, np:
Item - bazowy
ItemA: Item
ItemB: Item
ItemC: ItemA
Każdy z tych itemów ma mieć możliwość zapisu do bazy danych, do pliku binarnego, do XMLa itd. Generalnie kilka formatów zapisu.
Skupmy się na bazie danych, bo najłatwiej będzie opisać problem.
Każdy z tych typów ma osobną tabelę w bazie danych. W aplikacji mają osobne repozytoria.
Mam metodę do zapisu, której sygnatura wygląda tak:
public void Save(IEnumerable<Item> items)
Po prostu dostaję listę elementów do zapisu.
I teraz pojawia się problem - w jaki sposób zapisać odpowiednie itemy do odpowiednich tabel?
Najprostszą metodą, jaka się narzuca od razu jest posegregowanie tych itemów na listy odpowiednich typów, np:
List<ItemA> itemsA = GetItemsOfType<ItemA>(items);
List<ItemB> itemsB = GetItemsOfType<ItemB>(items);
itd
Metoda GetItemsOfType po prostu iterowałaby listę itemsów i zwracała listę tylko tych, którym zgadza się typ. I tu pojawia się - być może - problem. Pomijam już kwestie wydajnościowe (kilkukrotna iteracja tej samej listy - chociaż lista może się zmniejszać z każdym wywołaniem metody), bo nie ma co optymalizować "na pałę", ale głównie chodzi mi o lampkę, która mi się zapala: "Hej, porównujesz typy, czy na pewno wszystko w porządku?"
Później te podlisty zapisywałbym za pomocą odpowiednich repozytoriów:
itemsARepository.SaveAll(itemsA);
itemsBRepository.SaveAll(itemsB);
itd.
To rozwiązanie wydaje mi się sensowne. Ale czy można to zrobić jakoś lepiej? Bez porównywania typów?
Myślałem o tym, żeby itemy miały atrybuty, które określałyby miejsce ich zapisu. Dla bazy danych byłaby to nazwa tabeli, dla XML nazwa sekcji itd:
[SaveTo("ItemsA")]
class ItemA: Item
{
}
ale to rozwiązanie wydaje mi się mało eleganckie, poza tym nie mam pojęcia, które byłoby lepsze.
A co Wy o tym sądzicie?