AppDomain przydaje się gdy coś się gryzie z cudzym kodem

Duży system, kilka technologii. W tym coś napisanego w Javie. Okazało się, że jedna z klas Javy ma nazwę XmlSerializer. I właśnie ta klasa sprawia, że dziwnymi wyjątkami rzuca .NETowy XmlSerializer. Inna technologia, inne namespace’y – istna magia 🙂 Okazało się jeszcze, że gdy najpierw załaduje się .NETowy XmlSerializer to jest dobrze, a gdy najpierw Javowy to jest źle (czy odwrotnie – nieistotne).

Nie korzystać z XmlSerializera

A może skorzystać z DataContractSerializer? Niestety – nie można. Tamten XML potrzebuje atrybutów w znacznikach a akurat DataContractSerializer tego nie ma :/ Trzeba by napisać serializer „na piechotę” np z pomocą LINQ to XML. Już mi ciarki przechodzą po plecach, bo wiadomo, że „dobry kod to brak kodu w ogóle”.

Korzystać z XmlSerializer w osobnej AppDomain

To jest najlepsze rozwiązanie (zadziałało).

Funkcje które odpowiadają za serializację i deserializację umieścić w osobnej bibliotece (projekcie). Utworzyć osobną AppDomain, załadować do niej klasę z nowo utworzonej biblioteki (AppDomain.CreateInstanceAndUnwrap()) i zacząć korzystać z jej metod. Wyizolujemy dzięki temu pechowy XmlSerializer. Można przekazywać argumenty i zwracać wartości z metod wywoływanych w innej AppDomain – takie argumenty muszą jedynie dziedziczyć z MarshalByRefObject.

Dlaczego trzeba utworzyć nową bibliotekę? Gdy użyjemy jakiegokolwiek typu z jakiejś biblioteki to wszystkie typy z tej biblioteki zostaną załadowane. Nie możemy więc korzystać z metod/typów w sposób bezpośredni w kodzie (nie poprzez AppDomain), bo wszystko zostanie załadowane do aktualnej AppDomain.

To była taka high level opowiastka. Szczegółowy kod znajduję się w Passing values back and forth appdomains.

AppDomain

Reklamy
Ten wpis został opublikowany w kategorii Programowanie i oznaczony tagami , , , . Dodaj zakładkę do bezpośredniego odnośnika.