Получение интерфейса из динамически загруженной сборки
От: Владимир_  
Дата: 08.06.11 08:47
Оценка:
Доброе время суток.
Возникла проблема, прошу Вашей помощи.
История такова.
Мне надо динамически загрузить сборку, получить интерфейс для дальнейшей работы.

В упрощенном виде сборка такова
file1.cs

namespace ComService
{
    public sealed class ComServiceFacade
    {
       public static IComServiceFactory GetIComServiceFactory()
        {
            return (IComServiceFactory)(new CComServiceFactory());
        }
    }
    
        public interface IComServiceFactory
    {
        void zzz();
    }
}



file2.cs

namespace ComService
{
    internal sealed class CComServiceFactory : IComServiceFactory
    {
        public void zzz()
        {
            Console.WriteLine(this.GetType().ToString());
        }
    }
}



Client.cs


using ComService;
namespace CComConsoleTest
{

           Assembly a = Assembly.LoadFile(@"G:\zzz\CCom\ComService\bin\Debug\ComService.dll");
            Type facade = a.GetType("ComService.ComServiceFacade");
            object facadeobj = Activator.CreateInstance(facade, true);
            Type comfactorytype = a.GetType("ComService.CComServiceFactory");
            Type icft = comfactorytype.GetInterface("ComService.IComServiceFactory");
            
            IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { }));
}


На последней строке вылетает исключение InvalidCastException.
Ни как не пойму где грабли. Если есть идеи, поделитесь пожалуйста.
Re: Получение интерфейса из динамически загруженной сборки
От: HowardLovekraft  
Дата: 08.06.11 09:02
Оценка:
Здравствуйте, Владимир_, Вы писали:

В_>Ни как не пойму где грабли. Если есть идеи, поделитесь пожалуйста.

Лучше ответьте на вопрос, зачем вы пытаетесь еще раз загрузить сборку, в которой IComServiceFactory определен.
При том, что из сборки, в которой живет код клиента, IComServiceFactory доступен.

В результате, выделенное указывает на разные с т.з. CLR типы:
IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", ...));
Re: Получение интерфейса из динамически загруженной сборки
От: Аноним  
Дата: 08.06.11 09:12
Оценка:
Здравствуйте, Владимир_, Вы писали:

В_>Доброе время суток.

В_>Возникла проблема, прошу Вашей помощи.
В_>История такова.
В_>Мне надо динамически загрузить сборку, получить интерфейс для дальнейшей работы.

В_>В упрощенном виде сборка такова

В_>file1.cs

В_>
В_>namespace ComService
В_>{
В_>    public sealed class ComServiceFacade
В_>    {
В_>       public static IComServiceFactory GetIComServiceFactory()
В_>        {
В_>            return (IComServiceFactory)(new CComServiceFactory());
В_>        }
В_>    }
    
В_>        public interface IComServiceFactory
В_>    {
В_>        void zzz();
В_>    }
В_>}
В_>



В_>file2.cs


В_>
В_>namespace ComService
В_>{
В_>    internal sealed class CComServiceFactory : IComServiceFactory
В_>    {
В_>        public void zzz()
В_>        {
В_>            Console.WriteLine(this.GetType().ToString());
В_>        }
В_>    }
В_>}    
В_>



В_>Client.cs



В_>
В_>using ComService;
В_>namespace CComConsoleTest
В_>{

В_>           Assembly a = Assembly.LoadFile(@"G:\zzz\CCom\ComService\bin\Debug\ComService.dll");
В_>            Type facade = a.GetType("ComService.ComServiceFacade");
В_>            object facadeobj = Activator.CreateInstance(facade, true);
В_>            Type comfactorytype = a.GetType("ComService.CComServiceFactory");
В_>            Type icft = comfactorytype.GetInterface("ComService.IComServiceFactory");
            
В_>            IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, new object[] { }));
В_>} 
В_>


В_>На последней строке вылетает исключение InvalidCastException.

В_>Ни как не пойму где грабли. Если есть идеи, поделитесь пожалуйста.

У тебя facade тип Type. В последней строке метод какого объекта ты хочешь вызвать, там у тебя null.
Re[2]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 09:16
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, Владимир_, Вы писали:


В_>>Ни как не пойму где грабли. Если есть идеи, поделитесь пожалуйста.

HL>Лучше ответьте на вопрос, зачем вы пытаетесь еще раз загрузить сборку, в которой IComServiceFactory определен.
HL>При том, что из сборки, в которой живет код клиента, IComServiceFactory доступен.

HL>В результате, выделенное указывает на разные с т.з. CLR типы:

HL>
HL>IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", ...));
HL>


Извините, не совсем понял, где повторная загрузка.
Из сборки клиента доступен файл с определениями интерфейсов. Это сделано, чтобы использовать методы интерфейса, которому я привожу полученный из загруженной сборки объект.
Объясните пожалуйста, почему выделенный фрагменты указывают на разные типы.
Строка Type icft = comfactorytype.GetInterface("ComService.IComServiceFactory"); отрабатывает, то есть такой тип интерфейса присущ типу "ComService.CComServiceFactory".
Через InvokeMember"GetIComServiceFactory" я пытаюсь получить объект который и хочу привести к типу интерфейса, который ему присущ.
Не могу уловить момент двойной загрузки. Объясните пожалуйста.
Re[2]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 09:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Владимир_, Вы писали:



А>У тебя facade тип Type. В последней строке метод какого объекта ты хочешь вызвать, там у тебя null.

Заменил на
IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, facadeobj, null));

Тот же результат
Re[3]: Получение интерфейса из динамически загруженной сборк
От: Аноним  
Дата: 08.06.11 09:36
Оценка:
Здравствуйте, Владимир_, Вы писали:

В_>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, Владимир_, Вы писали:



А>>У тебя facade тип Type. В последней строке метод какого объекта ты хочешь вызвать, там у тебя null.

В_>Заменил на
В_>
В_>IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, facadeobj, null));
В_>

В_>Тот же результат

IComServiceFactory объявлен в двух зборках или одной? Просто две копии объявления типа в разных сборках есть разные типы.
Re: Получение интерфейса из динамически загруженной сборки
От: Владимир_  
Дата: 08.06.11 09:37
Оценка:
Попробовал

            dynamic tmpobject = (facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, facadeobj, null));
            tmpobject.zzz();

Говорит, что tmpobject не содержит метода zzz()
Re[4]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 09:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Владимир_, Вы писали:


В_>>Здравствуйте, Аноним, Вы писали:


А>>>Здравствуйте, Владимир_, Вы писали:



А>>>У тебя facade тип Type. В последней строке метод какого объекта ты хочешь вызвать, там у тебя null.

В_>>Заменил на
В_>>
В_>>IComServiceFactory tmpobject = (IComServiceFactory)(facade.InvokeMember("GetIComServiceFactory", BindingFlags.Default | BindingFlags.InvokeMethod, null, facadeobj, null));
В_>>

В_>>Тот же результат

А>IComServiceFactory объявлен в двух зборках или одной? Просто две копии объявления типа в разных сборках есть разные типы.

Объявление интерфейса есть в двух сборках. Получается, что это разные типы.
Подскажите пожалуйста, что мне надо сделать в сборке клиента, чтобы иметь возможность вызывать методы интерфейса в виде Interface.Method().
Если в сборке клиента я не объявлю этот интерфейс, то не смогу ссылать на его методы. Что то видимо я не так делаю.
Re[3]: Получение интерфейса из динамически загруженной сборк
От: HowardLovekraft  
Дата: 08.06.11 09:52
Оценка:
Здравствуйте, Владимир_, Вы писали:

В_>skipped

А вот
Автор: Владимир_
Дата: 08.06.11
и ответ...
Срочно читать Рихтера, CLR via C#, как минимум Part I CLR Basics и Part II Designing Types, и только потом садиться писать код.
Re[4]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 10:00
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, Владимир_, Вы писали:


В_>>skipped

HL>А вот
Автор: Владимир_
Дата: 08.06.11
и ответ...

HL>Срочно читать Рихтера, CLR via C#, как минимум Part I CLR Basics и Part II Designing Types, и только потом садиться писать код.

Вот прямо сейчас нет Рихтера под рукой. Это как минимум пару дней надо на покупку. А мне сейчас нужно только этот момент (загрузка сборки и получение интерфейса) заставить заработать. Нужен всего один вызов zzz() через IComServiceFactory.
Убрал объявление интерфейса в сборке клиента. Сижу и думаю, как же на него сослаться. Мне бы пару строк кода чтобы произвести этот вызов.
Как на зло, этот вызов нужен именно сегодня.
Re[5]: Получение интерфейса из динамически загруженной сборк
От: Аноним  
Дата: 08.06.11 10:04
Оценка:
Ну выдели интерфейс в треью сборку,а в загружаемую и клиенскую добавь на неё ссылку.
Re[5]: Получение интерфейса из динамически загруженной сборк
От: Victor Hytyk Украина  
Дата: 08.06.11 10:07
Оценка:
Здравствуйте, Владимир_, Вы писали:

А>>IComServiceFactory объявлен в двух зборках или одной? Просто две копии объявления типа в разных сборках есть разные типы.

В_>Объявление интерфейса есть в двух сборках. Получается, что это разные типы.
В_>Подскажите пожалуйста, что мне надо сделать в сборке клиента, чтобы иметь возможность вызывать методы интерфейса в виде Interface.Method().
В_>Если в сборке клиента я не объявлю этот интерфейс, то не смогу ссылать на его методы. Что то видимо я не так делаю.

Ну ясен пень что не так. тебе надо создать сборку, в которой будет твой интерфейс. Эту сборку подключаешь к сборке что загружаешь и к клиенту. Все. Класическая ситуация для создания системы плагинов.
-----------------------------------------
тут может быть ваша реклама
Re[6]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 10:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну выдели интерфейс в треью сборку,а в загружаемую и клиенскую добавь на неё ссылку.

Ссылка, имеется ввиду статическое подключение?
Re[7]: Получение интерфейса из динамически загруженной сборк
От: Victor Hytyk Украина  
Дата: 08.06.11 10:21
Оценка:
Здравствуйте, Владимир_, Вы писали:

В_>Здравствуйте, Аноним, Вы писали:


А>>Ну выдели интерфейс в треью сборку,а в загружаемую и клиенскую добавь на неё ссылку.

В_>Ссылка, имеется ввиду статическое подключение?
Естественно!
-----------------------------------------
тут может быть ваша реклама
Re[8]: Получение интерфейса из динамически загруженной сборк
От: Владимир_  
Дата: 08.06.11 10:47
Оценка:
Здравствуйте, Victor Hytyk, Вы писали:

VH>Здравствуйте, Владимир_, Вы писали:


В_>>Здравствуйте, Аноним, Вы писали:


А>>>Ну выдели интерфейс в треью сборку,а в загружаемую и клиенскую добавь на неё ссылку.

В_>>Ссылка, имеется ввиду статическое подключение?
VH>Естественно!

Ураааа, все заработало.
ОГРОМНЕЙШЕЕ спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.