Od dłuższego czasu korzystam z automappera, jest to genialne rozwiązanie gdy trzeba mapować jeden obiekt na drugi. Gdy w klasach, z i do której chcemy mapować wszystkie typy właściwości/pól i ich nazwy się zgadzają nie trzeba robić praktycznie nic, gdy pojawiają się inne nazwy, wystarczy tylko wskazać że pole właściwość W w klasie A to właściwość X w klasie B i tyle, raz i spokój do końca projektu. Gdy typy się nie zgadzają, można skorzystać z konwerterów, zarówno na poziomie właściwości jak i całych klas. Jeśli nie wiesz o czym mówię wróć 🙂 tutaj za kilka dnia, a ja obiecuje że popełnie wpis o automapperze. Opis – Automappera. Ale nie o tym chciałem napisać. Jeśli ktoś nie korzysta to polecam, jeśli potrzeba pomocy to proszę dać znać, a teraz do rzeczy.
Czasem konwertery aby dobrze wykonać swoją robotę potrzebują innej klasy, oczywiści można ją stworzyć w konstruktorze, ale to nie będzie ładne rozwiązanie, wszystko przez mocne wiązania, które ostatnio wyszły z mody. Na szczęście wymyślono wstrzykiwanie zależności, a automapper nie przeszkadza w skorzystaniu z tej idei. Co zrobić, aby to zadziałało?
Wystarczy taki kawałek kodu dodać do inicjalizacji automappera
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: Consolas, “Courier New”, Courier, Monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #a31515; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
1: public static void Initialize(IDependencyResolver current)
2: {
3: Mapper.Initialize(cfg => cfg.ConstructServicesUsing(t => current.GetService(t)));
4: // here goes other initialization of automapper
5: }
Pewnie się zapytacie skąd i jak jest wołane? Ja bym się pytał. Więc tak to robię ja, w Application_Start w global.asax.cs
1: ModelMapper.Initialize(DependencyResolver.Current);
Potem gdy chcemy skorzystać z jakiegoś konwertera, na liście parametrów w kontruktorze można podać to czego potrzbujemy i czekać aż framework zrobic swoją magię:
1: public class Id2ConceptStatistics : TypeConverter<long, ConceptStatistics>
2: {
3: private readonly IUnitOfWork unitOfWork;
4:
5: public Id2ConceptStatistics(IUnitOfWork unitOfWork)
6: {
7: this.unitOfWork = unitOfWork;
8: }
9:
10: protected override ConceptStatistics ConvertCore(long id)
11: {
12: var conceptStatistics = this.unitOfWork.ConceptStatistics.GetByID(id);
13: var result = conceptStatistics ?? new ConceptStatistics();
14: return result;
15: }
16: }
Powyżej przykład na to jak z long (który jest id) można zmapować na pełno prawną klasę, która jest zagnieżdżona gdzieś w innej klasie.
To tyle.