вот моя проблема, которую нужно решить: у меня есть плагин-структура для мультимедийных шоу, которая позволяет реализовывать типы мультимедиа во внешних сборках путем создания подклассов из базового класса в моей среде.Шоу содержит список типов медиа.Шоу загружаются и сохраняются в формате XML с использованием XmlSerializer
.Это все работает, даже с программным отображением типов для плагина MediaTypes.
Однако я хочу иметь возможность загружать XML-файлы, содержащие MediaTypes , которые не известны , поскольку плагин недоступен.
Для иллюстрации вот такой файл XML:
<MultiMediaShow>
<MediaTypes>
<SomeType />
<SomeType />
<AnotherType />
<UnknownTypeFromPluginNotLoaded />
</MediaTypes>
</MultiMediaShow>
В приведенном выше примере я предполагаю 2 "известных" MediaTypes SomeType
и AnotherType
, исходящих из 2 сборок плагинов,Третий тип (UnknownTypeFromPluginNotLoaded
) неизвестен.
Я уже могу десериализовать такие неизвестные объекты, но борюсь с сериализацией.В моем приложении у меня есть следующий код:
// To be implemented / subclassed by plugin assembly types
public abstract class MediaType
{
}
public class UnknownMediaType : MediaType
{
[XmlAnyElement]
public XmlElement[] UnknownChildElements;
[XmlAnyAttribute]
public XmlAttibute[] UnknownAttributes;
[XmlIgnore]
public string XmlTagName; // stores the xml element tag name in the original document
}
[XmlRoot("MultimediaShow")]
public class MultimediaShow
{
public List<MediaType> MediaTypes = new List<MediaType>();
}
При десериализации этого с помощью XmlSerializer
я использую событие UnknownElement
и вручную вставляю элемент UnknownMediaType
в show.MediaTypes
:
void HandleUnknownElements(Show show, List<XmlElementEventArgs> unknownElementEvents, XmlAttributeOverrides overrides)
{
// add a root attribute to UnknownMediaType
XmlAttributes attrs = new XmlAttributes();
XmlRootAttribute xmlRoot = new XmlRootAttribute(e.Element.Name);
attrs.XmlRoot = xmlRoot;
XmlAttributeOverrides o = new XmlAttributeOverrides();
o.Add(typeof(UnknownMediaObject), attrs);
// use a new XmlSerializer and a memory stream for deserializting the object as UnknownMediaType.
XmlSerializer xmlSerializer = new XmlSerializer(typeof(UnknownMediaType), o);
using (MemoryStream memoryStream = new MemoryStream())
{
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.ImportNode(e.Element, true));
doc.Save(memoryStream);
memoryStream.Position = 0;
try
{
// deserialize the object, store the XML element name and insert it into the chapter
UnknownMediaType t = xmlSerializer.Deserialize(memoryStream) as UnknownMediaObject;
t.XmlTagName = e.Element.Name;
show.MediaTypes.Add(t);
}
catch (Exception exc)
{
System.Diagnostics.Debug.WriteLine(exc.ToString());
//return objectType.IsByRef ? null : Activator.CreateInstance(objectType);
}
}
}
Проблема BIG BIG заключается в том, что такое событие недоступно при сериализации объекта.В результате я получаю (не очень удивительно):
<MultiMediaShow>
<MediaTypes>
<SomeType />
<SomeType />
<AnotherType />
<UnknownMediaType /> // !!!! was 'UnknownTypeFromPluginNotLoaded' !!!!
</MediaTypes>
</MultiMediaShow>
Однако, это явно не то, что я десериализовал.Итак, вопрос в том, как бы я лучше всего решил эту проблему?!?!
Вся помощь высоко ценится !!
Ура, Феликс
ОБНОВЛЕНИЕ
Мне было интересно, можно ли программно генерировать классы, производные от UnknownMediaType
и получившие имя класса из UnknownMediaType.XmlTagName
.Или, альтернативно, иметь атрибут для указания имени тега XML класса ??
Cheers, Felix