XMLSerializer не удалось сохранить / загрузить при вызове из сборки, динамически загруженной из родительского приложения? - PullRequest
0 голосов
/ 01 июля 2010

Я пишу плагин DLL для приложения. Приложение загружает сборки плагинов через:

assembly = Assembly.Load(System.IO.File.ReadAllBytes(filename)); 

Проблема проявляется, когда я пытаюсь сериализовать / десериализовать класс plublic. Я сузил это до сериализации:

public BindingList<MyClass> MyClasses
    { get; set; }

Если я это прокомментирую, проблем не будет. Если я попытаюсь сериализовать с:

        public static void SaveSettingsFile()
        {
            try
            {
                XmlSerializer ser = new XmlSerializer(typeof(GameTimeSettings));

                TextWriter writer = new StreamWriter(SettingPath);
                ser.Serialize(writer, Settings.Instance);
                writer.Close();
            }
            catch (Exception e)
            {
                Logger.ReportException("SaveSettingsFile", e);
                Logger.ReportException("SaveSettingsFile->InnerException", e.InnerException);
            }
        }

Исключение выдается на ser.Serialize (писатель, Settings.Instance):

System.InvalidOperationException Msg=There is an error in XML document (0,, 0). ->
InnerException: Object reference not set to an instance of an object.

Мой класс имеет пустой конструктор по умолчанию. Я пытался с помощью Sgen. В простом тестовом приложении, которое я написал, сериализация работает нормально ... это происходит только при сбое динамической загрузки сборки.

Кроме того, из этих двух потоков

http://forums.gbpvr.com/showthread.php?30384-XMLSerializer-Problems-with-Plugins, http://forums.gbpvr.com/showthread.php?32197-System.XML-Deserialization

Я знаю, что могу изменить тип с BindingList на ArrayList и заставить его работать; Тем не менее, я хотел бы, чтобы привязка данных работала, так как есть довольно много настроек для управления.

Любой вклад будет оценен.

Ответы [ 2 ]

0 голосов
/ 06 июня 2012

Извините, что поднял это из могилы, но сегодня я столкнулся с подобной проблемой, и это был первый результат Google, поэтому я решил поделиться.

Похоже, это общий случай проблемы, с которой я столкнулся некоторое время назад при попытке написать пользовательскую задачу MSBuild (в основном, плагин). Я писал об этом на форумах MSDN .

Вот самая важная часть комментария, просто замените MSBuild для любого приложения, имеющего архитектуру плагинов, и библиотеку CruiseControl.NET для любой библиотеки, которая использует XmlSerializer:

Рассматриваемая библиотека - это библиотека удаленного взаимодействия для CruiseControl.NET компании ThoughtWork, которая использует .NET Remoting для некоторых активированных клиентом объектов. Когда вы пытаетесь активировать объект, двоичный сериализатор .NET начинает работать, пытаясь выяснить, откуда загрузить сборку ThoughtWorks.CruiseControl, чтобы он мог прочитать объект (ThoughtWorks.CruiseControl.Remote.dll в 1.4.4SP1, который мы проблема заключается в том, что логика GetAssembly в Binary Serializer не понимает, что MSBuild выполнил вуду для загрузки пользовательской сборки из произвольного местоположения.

Поэтому по умолчанию он пытается искать в том же каталоге, в котором находится программа, в соответствии с http://msdn.microsoft.com/en-us/library/yx7xezcf%28v=VS.100%29.aspx, что означает, что если он не найдет его в GAC, он начнет проверять, откуда была программа запущен, и поскольку MSBuild был запущен из папки% FrameworkDir% /% FrameworkVersion%, маловероятно, что он найдет нужную сборку.

Это объясняет, почему вы не увидите эту проблему в консольном приложении (сборка, скорее всего, находится прямо рядом с консольным приложением)

Решение, предлагаемое в сообщении на форуме MSDN, также применимо здесь, в основном они добавили дополнительный обработчик событий, чтобы попытаться выполнить поиск в известном месте, снова я процитировал соответствующие части:

Для тех, кому все равно, обходной путь - зарегистрировать обработчик для события AppDomain.AssemblyResolve и для Assembly.LoadFrom () там.

Лично меня это пугает, но это единственное найденное мной решение, которое работает, немного больше прибегая к помощи, не показало мне проблему Microsoft Connect для этого, но, скорее всего, оно не будет исправлено или разработано .

0 голосов
/ 01 июля 2010

Комментарий Джона Сондерса пока выглядит правильным для этого, вы, вероятно, не инициализируете MyClasses.

Поскольку вы говорите, что он работает нормально с SGen, вы также можете проверить, есть ли что-то делатьс флагами компиляции, например, попробуйте установить его в релиз и посмотреть, изменит ли это что-то.

...