Есть большая СИСТЕМА — приложение, написанное на C#. В одном солюшине много проектов ну и т.д. Хочется сделать плагинную систему, чтобы другие люди писали плагины (dll-ки) и использовали их в приложении. Для этого были взяты классы и интерфейсы из разных проектов этого солюшена и сделаны стабы по ним. Стабы это когда мы выкидываем код, заменяя его на return или return null или return (какое-нибудь значение примитивного типа); Т.е. у нас от классов остается только скелет. Так вот, все эти стабы подсовываем пользователю в качестве одной dll. Он ее использует для того, чтобы просто скомпиляться. Т.е. если ему необходимо имплементить интерфейс — берет его из стабов.. Нужен внутренний логгер, ссылается на класс из стабов..
Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
Как вариант можно сделать отдельную библиотеку, которой пользуются и приложение и разработчики плагинов — но это бы очень не хотелось.. Ибо придется городить туда много чего (логгеры, интерфейсы одни, интерфейсы другие и т.д) или поставлять кучу dll в SDK для плагинов.. этого бы тоже не хотелось.. Спасибо. Жду Ваших советов
Под сервером и клиентом я, конечно-же, иммел в виду хост и плагины
У кого о чем болит, так сказать...
EW>Здравствуйте, stalk, Вы писали:
EW>Вместо dll со стабами сделать dll с интерфейсами и положить ее и на сервер и на клиент. EW>Классы на сервере наследовать от этих интерфейсов
Здравствуйте, Ed.ward, Вы писали:
EW>Здравствуйте, Ed.ward, Вы писали:
EW>Под сервером и клиентом я, конечно-же, иммел в виду хост и плагины :)
EW>У кого о чем болит, так сказать... :)
EW>>Здравствуйте, stalk, Вы писали:
EW>>Вместо dll со стабами сделать dll с интерфейсами и положить ее и на сервер и на клиент. EW>>Классы на сервере наследовать от этих интерфейсов
EW>Ed.ward
Ed.ward, это понятно. я предлагал так сделать в своем посте. Но! опять же, этого делать не хочется.. Ибо, в моем случае либо предется перетаскивать из многих проектов в один.. Или провайдить пользователю много библиотек.. =(( Какой-же сакс этот дот нет в этом смысле.. не то что джава.. =((( Ау.. может кто-нибудь еще что-нибудь посоветует?
Здравствуйте, stalk, Вы писали:
S>Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
Здравствуйте, AlexZu, Вы писали:
AZ>Здравствуйте, stalk, Вы писали:
S>>Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
AZ>Как загружаете сборки?
В смысле как? А какие варианты? пользователь собирает dll и потом загружает ее в приложение.. мы собственно и используем то, что написано в библиотеке.. Я понимаю, что всяческие ошибки происходят из-за супер навороченной системы безопасности.. Которая и мешает.. В джаве для этого есть всякие NoSuchMethodException и иже с ним..
AlexZu, а какие именно параметры сборки интересуют?
Здравствуйте, stalk, Вы писали:
AZ>>Как загружаете сборки?
S>В смысле как? А какие варианты? пользователь собирает dll и потом загружает ее в приложение.. мы собственно и используем то, что написано в библиотеке.. Я понимаю, что всяческие ошибки происходят из-за супер навороченной системы безопасности.. Которая и мешает.. В джаве для этого есть всякие NoSuchMethodException и иже с ним..
S>AlexZu, а какие именно параметры сборки интересуют?
Имеедось ввиду, как хост загружает сборки плагинов: Assembly.LoadFrom, Assembly.Load, etc.. (эти методвы используют различный контекст загрузки сборок)
Не сразу уловил, что "одни и те же" интерфейсы используемые хостом и плагинами у вас в разных сборках, т.к. полное имя типа в .NEt также включает в себя имя сборки, так делать неправильно, поскольку будут разные типы.
Здравствуйте, stalk, Вы писали:
S>Всем привет!
S>Наступил на грабли .NET. Ситуация такая.
S>Есть большая СИСТЕМА — приложение, написанное на C#. В одном солюшине много проектов ну и т.д. Хочется сделать плагинную систему, чтобы другие люди писали плагины (dll-ки) и использовали их в приложении. Для этого были взяты классы и интерфейсы из разных проектов этого солюшена и сделаны стабы по ним. Стабы это когда мы выкидываем код, заменяя его на return или return null или return (какое-нибудь значение примитивного типа); Т.е. у нас от классов остается только скелет. Так вот, все эти стабы подсовываем пользователю в качестве одной dll. Он ее использует для того, чтобы просто скомпиляться. Т.е. если ему необходимо имплементить интерфейс — берет его из стабов.. Нужен внутренний логгер, ссылается на класс из стабов..
S>Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
S>Как вариант можно сделать отдельную библиотеку, которой пользуются и приложение и разработчики плагинов — но это бы очень не хотелось.. Ибо придется городить туда много чего (логгеры, интерфейсы одни, интерфейсы другие и т.д) или поставлять кучу dll в SDK для плагинов.. этого бы тоже не хотелось.. Спасибо. Жду Ваших советов
Два интерфейса, объявленные в двух разных сборках не могут быть покасщены один на другой. Если хочется, чтобы были просто два варианта одной сборки с разной реализацией, можно попробовать проследить чтобы:
1. Все свойства сборок прописанные в AssemblyInfo.cs и настройках проекта были идентичны.
2. Все ссылки на сборку были не ссылками на результаты билда некоторого проекта, а на бинарный файл.
Но сама идея кажется порочной. Стандартный подход к решению этой проблемы заключается в том, что объявляется сборка с интерфейсами и делается несколько сборок, реализующих эти интерфейсы. В рантайме выбор между конкретными реализациями можно делать самому (на эту тему есть много дизайн патернов), или использовать какой-нибудь готовый тул, например, Winsdor Castle.
Здравствуйте, stalk, Вы писали:
S>Всем привет!
S>Наступил на грабли .NET. Ситуация такая.
S>Есть большая СИСТЕМА — приложение, написанное на C#. В одном солюшине много проектов ну и т.д. Хочется сделать плагинную систему, чтобы другие люди писали плагины (dll-ки) и использовали их в приложении. Для этого были взяты классы и интерфейсы из разных проектов этого солюшена и сделаны стабы по ним. Стабы это когда мы выкидываем код, заменяя его на return или return null или return (какое-нибудь значение примитивного типа); Т.е. у нас от классов остается только скелет. Так вот, все эти стабы подсовываем пользователю в качестве одной dll. Он ее использует для того, чтобы просто скомпиляться. Т.е. если ему необходимо имплементить интерфейс — берет его из стабов.. Нужен внутренний логгер, ссылается на класс из стабов..
S>Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
S>Как вариант можно сделать отдельную библиотеку, которой пользуются и приложение и разработчики плагинов — но это бы очень не хотелось.. Ибо придется городить туда много чего (логгеры, интерфейсы одни, интерфейсы другие и т.д) или поставлять кучу dll в SDK для плагинов.. этого бы тоже не хотелось.. Спасибо. Жду Ваших советов
Плугин ничего не имплементит, имеет лишь публичные методы. При загрузке плугина конструируешь сборку, там класс, имплементирующий интерфейс, а в его методах — вызовы методов плугина.
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, stalk, Вы писали:
S>>Всем привет!
S>>Наступил на грабли .NET. Ситуация такая.
S>>Есть большая СИСТЕМА — приложение, написанное на C#. В одном солюшине много проектов ну и т.д. Хочется сделать плагинную систему, чтобы другие люди писали плагины (dll-ки) и использовали их в приложении. Для этого были взяты классы и интерфейсы из разных проектов этого солюшена и сделаны стабы по ним. Стабы это когда мы выкидываем код, заменяя его на return или return null или return (какое-нибудь значение примитивного типа); Т.е. у нас от классов остается только скелет. Так вот, все эти стабы подсовываем пользователю в качестве одной dll. Он ее использует для того, чтобы просто скомпиляться. Т.е. если ему необходимо имплементить интерфейс — берет его из стабов.. Нужен внутренний логгер, ссылается на класс из стабов..
S>>Все замечательно. НО! Когда загружаю скомпиленную библиотечку в приложении он мне пишет, что существуют два интерфейса (назовем их IPlugin) с разными гуидами.. Меня это сильно расстроило.. Как джава разработчик я на такие грабли еще не наступал.. Прописал для этого интерфейса гуид руками.. в приложении и в стаб библиотеке (один и тотже есесно). НО.. все равно не может скастить зараза.. Господа, подскажите как мне быть в такой ситуации.
S>>Как вариант можно сделать отдельную библиотеку, которой пользуются и приложение и разработчики плагинов — но это бы очень не хотелось.. Ибо придется городить туда много чего (логгеры, интерфейсы одни, интерфейсы другие и т.д) или поставлять кучу dll в SDK для плагинов.. этого бы тоже не хотелось.. Спасибо. Жду Ваших советов
A>Плугин ничего не имплементит, имеет лишь публичные методы. При загрузке плугина конструируешь сборку, там класс, имплементирующий интерфейс, а в его методах — вызовы методов плугина.
A>Динамический wrapper одним словом.
Ой.. нет.. тогда просто не заставить будет писать плагины правильно.. интерфейс заставляет 3rd party программера сделать нужные публичные методы..
Здравствуйте, stalk, Вы писали:
A>>Плугин ничего не имплементит, имеет лишь публичные методы. При загрузке плугина конструируешь сборку, там класс, имплементирующий интерфейс, а в его методах — вызовы методов плугина.
A>>Динамический wrapper одним словом.
S>Ой.. нет.. тогда просто не заставить будет писать плагины правильно.. интерфейс заставляет 3rd party программера сделать нужные публичные методы..
А кто мешает сделать интерфейс, заимплементить его в плагине, получить таким образом нужные публичные методы и их-то и вызывать из враппера?
Здравствуйте, stalk, Вы писали:
EW>>Под сервером и клиентом я, конечно-же, иммел в виду хост и плагины
EW>>У кого о чем болит, так сказать...
EW>>>Здравствуйте, stalk, Вы писали:
EW>>>Вместо dll со стабами сделать dll с интерфейсами и положить ее и на сервер и на клиент. EW>>>Классы на сервере наследовать от этих интерфейсов
EW>>Ed.ward
S>Ed.ward, это понятно. я предлагал так сделать в своем посте. Но! опять же, этого делать не хочется.. Ибо, в моем случае либо предется перетаскивать из многих проектов в один.. Или провайдить пользователю много библиотек.. =(( Какой-же сакс этот дот нет в этом смысле.. не то что джава.. =((( Ау.. может кто-нибудь еще что-нибудь посоветует?
сакс не дотнет, а стиль
Ed.ward вам верно посоветовал, вы пытались изобрести велосипед под названием "интерфейсы", изобретать ничего не нужно, в C# есть ключевое слово "interface".
Делать систему плагинов не используя для этого интерфейсы глупо.
Если вам не нравятся интерфейсы, вам прийдется написать значительно больше кода, который будет значительно менее расширяем. В этом случае есть еще как минимум два варианта:
1. (наиболее удобный вариант) Не подписывать сборки плагинов строгим именем и вместо сборки с заглушками подкладывать сборку с реальным кодом
2. (посложней, понадобится Reflection) Создавать требуемый экземляр класса из сборки с плагином через Assembly.Load и CreateInstance
однако я думаю, что отказываясь от интерфейсов вы совершаете совершенно гиблую ошибку, сильно усложняя себе жизнь