У меня есть небольшая проблема, которая мучила мою голову в течение нескольких дней. Я пишу что-то вроде ясли для виртуальной гоночной лиги.
Я хочу сохранить все свои данные в одном XML-файле, чтобы к нему можно было легко получить доступ с нескольких сторон.
Однако из-за ограничения xml-сериализатора id должен сделать все мои классы общедоступными. Для этого я написал интерфейс
с помощью которого я хочу преобразовать мои оригинальные управляющие объекты (со всеми функциями) в необработанные данные, содержащие объекты для сериализации xml.
Чтобы иметь возможность отслеживать, кто создал / изменил что-то, что нужно каждому, для хранения поля «ChangeNotification».
Для этого я создал базовый класс с этими полями, из которого получены мои классы контейнеров.
А теперь возникает проблема: если я сериализую только часть этого, все работает нормально. Но как только я сериализую объект, который содержит другой объект, полученный из той же базы,
мой "CreateChangeNotification" будет присутствовать только в верхнем объекте.
Я не понимаю, почему это происходит, поскольку в объектах явно хранятся два его экземпляра, в которых одновременно хранятся разные значения.
Извините за длинный фрагмент кода, но это то, что мне было нужно, чтобы воссоздать проблему, и, похоже, это происходит каждый раз с этой структурой.
[Serializable()]
public class DataManagerXmlContainer<DataContainerType> : IDataManagerContainer
{
[XmlElement("Created")]
public ChangeNotificationXmlContainer created;
[XmlIgnore()]
public IChangeNotificationDataContainer Created { get => created; set => created = new ChangeNotificationXmlContainer(value); }
//[XmlElement("Changed")]
//public ChangeNotificationXmlContainer changed;
//[XmlIgnore()]
//public IChangeNotificationDataContainer LastChange { get => changed; set => changed = new ChangeNotificationXmlContainer(value); }
public DataManagerXmlContainer() { }
}
[Serializable()]
public class ReviewDataXmlContainer : DataManagerXmlContainer<IReviewDataContainer>, IReviewDataContainer
{
[XmlArray("CommentList")]
[XmlArrayItem("Comment")]
public List<ReviewCommentXmlContainer> comments = new List<ReviewCommentXmlContainer>();
[XmlIgnore()]
public ICollection<IReviewCommentDataContainer> Comments
{
get => comments.Cast<IReviewCommentDataContainer>().ToList();
set => comments = value.ToList().ConvertAll(x => new ReviewCommentXmlContainer(x));
}
public ReviewDataXmlContainer() { }
public ReviewDataXmlContainer(string authorID)
{
created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
}
public void AddComment(IReviewCommentDataContainer comment)
{
comments.Add(new ReviewCommentXmlContainer(comment));
}
}
[Serializable()]
public class ReviewCommentXmlContainer : DataManagerXmlContainer<IReviewCommentDataContainer>, IReviewCommentDataContainer
{
[XmlAttribute("author_id")]
public string AuthorAdminID { get; set; }
public string Text { get; set; }
public ReviewCommentXmlContainer() { }
public ReviewCommentXmlContainer(string authorID, string text)
{
created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
AuthorAdminID = authorID;
Text = text;
}
public ReviewCommentXmlContainer(IReviewCommentDataContainer dataContainer)
{
AuthorAdminID = dataContainer.AuthorAdminID;
Text = dataContainer.Text;
}
}
[Serializable()]
public class ChangeNotificationXmlContainer : IChangeNotificationDataContainer
{
[XmlAttribute("author_id")]
public string AuthorID { get; set; }
[XmlAttribute("time")]
public DateTime Time { get; set; }
public ChangeNotificationXmlContainer() { }
public ChangeNotificationXmlContainer(string id, DateTime time)
{
AuthorID = id;
Time = time;
}
public ChangeNotificationXmlContainer(IChangeNotificationDataContainer dataContainer)
{
AuthorID = dataContainer.AuthorID;
Time = dataContainer.Time;
}
}
public interface IChangeNotificationDataContainer
{
string AuthorID { get; set; }
DateTime Time { get; set; }
}
public interface IDataManagerContainer
{
IChangeNotificationDataContainer Created { get; set; }
}
public interface IReviewDataContainer : IDataManagerContainer
{
ICollection<IReviewCommentDataContainer> Comments { get; set; }
void AddComment(IReviewCommentDataContainer comment);
}
public interface IReviewCommentDataContainer : IDataManagerContainer
{
string AuthorAdminID { get; set; }
string Text { get; set; }
}
и код программы:
class Program
{
static void Main(string[] args)
{
IReviewCommentDataContainer comment = new ReviewCommentXmlContainer("12345", "This is a test");
Task.Delay(1000).Wait();
ReviewDataXmlContainer review = new ReviewDataXmlContainer("23456");
review.AddComment(comment);
XmlSerializer serializer = new XmlSerializer(typeof(ReviewDataXmlContainer));
TextWriter writer = new StreamWriter("Test.xml");
serializer.Serialize(writer, review);
//Task.Delay(-1).Wait();
}
}
Вот так выглядит мой xml:
<?xml version="1.0" encoding="utf-8"?>
<ReviewDataXmlContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Created author_id="23456" time="2018-11-16T06:56:16.5425819+01:00" />
<CommentList>
<Comment author_id="12345">
<Text>This is a test</Text>
</Comment>
</CommentList>
</ReviewDataXmlContainer>
Как видите, элемент Создать комментария просто отсутствует.