Форум программистов CODEBY.NET Хостинг в Беларуси — Active Technologies

Разработка бизнес сайтов

Нужны клиенты? Тогда сюда быстрее...
X   Сообщение сайта
(Сообщение закроется через 2 секунды)

Здравствуйте, гость ( Вход | Регистрация )




> Динамически подключенная Dll и десериализация, При десериализации не находит соответсвующую dll
Vitone
Вставить ник
сообщение 31:05:2008, 21:41
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 16
Регистрация: 31:05:2008
Пользователь №: 17 723



Репутация:   0  


У меня такая проблемма. Существует иеархия классов, при чем базовый класс и большое множество производных от него классов раскиданы по разным dll-кам (в одной - сколько угодно производных классов). И мне необходимо сохранять состояние классов (использую SOAP сериализацию). Так вот, если эти dll-ки подключаю статически, то все нормально, но когда динамически - возникает ошибка при попытке десериализировать, при чем на этапе разбора элементов XML файла.

Сериализация:
CODE
SoapFormatter formatter = new SoapFormatter();
FileStream stream = File.Open(fileName, FileMode.Create);
FbdProgram tmp=new FbdProgram();
formatter.Serialize(stream, tmp);
stream.Close();


Десериализация:
CODE
Stream stream = File.Open(fileName, FileMode.Open);
SoapFormatter formatter = new SoapFormatter();
FbdProgram tmp=new FbdProgram();
tmp = (FbdProgram)formatter.Deserialize(stream);
stream.Close();


Фрагмент сохраненного XML файла:
<a2:MUL_INT id="ref-10" xmlns:a2="http://schemas.microsoft.com/clr/nsassem/FBDVisualBlocks.VisualBlocks/FBDVisualBlocks%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db98b95bcb02affd6">

Ошибка происходит при десериализации на строчке:
tmp = (FbdProgram)formatter.Deserialize(stream);

При этом она имеет следующий вид:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.Formatters.Soap.dll

Additional information: Parse Error, no assembly associated with Xml key a2:http://schemas.microsoft.com/clr/nsassem/FBDVisualBlocks.VisualBlocks/FBDVisualBlocks%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Db98b95bcb02affd6 MUL_INT

Большое спасибо!
Подняться вверх 
 
Сообщение #1
 
Новая тема 
Ответов (1 - 7)
Pasha
Вставить ник
сообщение 1:06:2008, 08:44
Цитата Ответить 


Божественный
*****

Группа: Модеры
Сообщений: 1 293
Регистрация: 17:05:2006
Из: Минск
Пользователь №: 4 257



Репутация:   28  


Vitone
Динамически - это как?
Подняться вверх 
 
Сообщение #2
Vitone
Вставить ник
сообщение 1:06:2008, 10:42
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 16
Регистрация: 31:05:2008
Пользователь №: 17 723



Репутация:   0  


Библиотеки подключаются так: ищутся все dll-ки в заданном каталоги и с заданным атрибутом:

Вот привожу код:
CODE
public void LoadDlls(string path)
{
DirectoryInfo Dir = new DirectoryInfo(path);
FileInfo[] files = Dir.GetFiles("*.dll");
foreach (FileInfo file in files)
{
a = Assembly.LoadFrom(Application.StartupPath + "\\" + path+"\\"+file.Name/*.Substring(0, file.Name.Length - 4)*/);
_types = a.GetTypes();
foreach (Type type in _types)
{
ListOfTypes.Add(type);
}
}

}
Подняться вверх 
 
Сообщение #3
Pasha
Вставить ник
сообщение 1:06:2008, 17:36
Цитата Ответить 


Божественный
*****

Группа: Модеры
Сообщений: 1 293
Регистрация: 17:05:2006
Из: Минск
Пользователь №: 4 257



Репутация:   28  


Vitone
Похоже, SoapFormatter не заморачивается с поиском библиотек, и тупо сам загружает их через Assembly.Load. А тот, в свою очередь, тупо отвечает что не может загрузить, т.к. не может найти файл на диске и сверить с уже загруженным. Пропиши в конфиге configuration/runtime
/assemblyBinding/probing/@privatePath к папке с длл-ками. Или просто помогай рантайму их резолвить, примерно так:
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Soap;

namespace ConsoleApplication2
{
    class Program
    {
        private static Assembly sampleAssembly;

        static void Main(string[] args)
        {
            sampleAssembly = Assembly.LoadFrom(@"D:\Projects\sl1\ClassLibrary1\bin\Debug\ClassLibrary1.dll");

            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

            Stream stream = File.Open(@"D:\temp.txt", FileMode.Open);
            SoapFormatter formatter = new SoapFormatter();
            object tmp = formatter.Deserialize(stream);
            stream.Close();
        }

        static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name == sampleAssembly.FullName)
            {
                return sampleAssembly;
            }
            else
            {
                return null;
            }
        }
    }
}
Звиняй, код на коленке написан.
ЗЫ. И еще, в десериализации ты зачем-то объект создаешь лишний раз:
            FbdProgram tmp=new FbdProgram();
            tmp = (FbdProgram)formatter.Deserialize(stream);
Подняться вверх 
 
Сообщение #4
Vitone
Вставить ник
сообщение 1:06:2008, 18:19
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 16
Регистрация: 31:05:2008
Пользователь №: 17 723



Репутация:   0  


Цитата(Pasha @ 1:06:2008 - 19:36) *
Пропиши в конфиге configuration/runtime
/assemblyBinding/probing/@privatePath к папке с длл-ками.


А можно об этом поподробней? Никогда раньше не рограмил с использованием dll-ок. А за помощь спасибо, сейчас проверю!

Цитата(Pasha @ 1:06:2008 - 19:36) *
Похоже, SoapFormatter не заморачивается с поиском библиотек, и тупо сам загружает их через Assembly.Load

Твоя правда, Pasha, SoapFormatter не ищет dll-ки в моей папке, а ищет в той, где сам ехе-шник. Но мне очень желательно, чтоб эти dll-ки были в отдельной папке, поскольку предполагается, что их количество будет расти, и, возможно писть их будет кто-то другой.
Подняться вверх 
 
Сообщение #5
Pasha
Вставить ник
сообщение 1:06:2008, 19:44
Цитата Ответить 


Божественный
*****

Группа: Модеры
Сообщений: 1 293
Регистрация: 17:05:2006
Из: Минск
Пользователь №: 4 257



Репутация:   28  


Цитата(Vitone @ 1:06:2008 - 20:19) *
А можно об этом поподробней? Никогда раньше не рограмил с использованием dll-ок.
Это секция конфига приложения, в которой можно прописать доп. пути для поиска сборок:
]]>http://msdn.microsoft.com/en-us/library/823z9h8w.aspx]]>, и дальше по ссылками "How the Runtime Locates Assemblies"
Подняться вверх 
 
Сообщение #6
Vitone
Вставить ник
сообщение 2:06:2008, 15:21
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 16
Регистрация: 31:05:2008
Пользователь №: 17 723



Репутация:   0  


Создал конфигурационный файл Program.exe.config и поместил в папку с экзешником (bin\Debug), прописал в нем такие строчки:

<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding>
<probing privatePath="Blocks;"/>
</assemblyBinding>
</runtime>
</configuration>

Но SoapFormatter все равно не находит сборки, только в папке экзешника.
Что я не так сделал?

Сообщение отредактировал Vitone - 2:06:2008, 15:34
Подняться вверх 
 
Сообщение #7
Vitone
Вставить ник
сообщение 2:06:2008, 20:00
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 16
Регистрация: 31:05:2008
Пользователь №: 17 723



Репутация:   0  


Всё, разобрался, спасибо. Вот это мне помогло:
]]>http://www.intuit.ru/department/pl/visualcsharp/9/6.html]]>
rolleyes.gif
Подняться вверх 
 
Сообщение #8


Быстрый ответ  Ответить  Новая тема 

> Быстрый ответ
Полужирный
Курсив
Подчеркнутый
Вставить изображение
Смайлики
Цитата
Код
 
 Отправлять уведомления об ответах на e-mail |  Включить смайлики |  Добавить подпись |  AJAX?
   

 

RSS Текстовая версия Сейчас: 8:09:2008 - 05:07
с нами можно связаться по:
телефону: +375-(29)-632-60-67
e-mail:info@codeby.net