Все на C#
Итак, есть:
1) Прога с поддержкой плагинов
2) Ядро, в котором написан абстрактный класс Plugin (kernel.dll)
Как создаются сейчас плагины?
1) Разработчик качает kernel.dll
2) Указывает в References эту сборку и указывает namespace'ы
3) Создает свой класс:
public class MyPlugin : Plugin { }
4) переопределяет абстрактные функции, определенные в ядре.
Собственно плагин готов...

И загружается из сборки как класс Plugin, но в нем уже все переопределено и наш плагин работает.
Хотелось избавиться от некоторых проблем...

, которые все сводятся к тому, чтобы не давать качать класс kernel.dll разработчикам.
Например, в самом простом случае дать только Interface с методами, которые требует переопределить, но тогда внутри этих методов нельзя будет вызывать некоторые вспомогательные функции, определенные в ядре.
Вопрос: как сделать поддержку плагинов, чтобы не давать никаких реализованных классов и функций разработчикам плагинов?
Чтобы все было ясно, простой гипотетический пример:
Я разработчик фотошопа, хочу сделать поддержку плагинов — сжатие изображений. Разработчикам требуется переопределить функции Compress и DeCompress, при этом вызывая ядерную функцию GetQuality — качество сжатия.
Я мог бы дать им абстрактный класс в котором определена функция GetQuality, но не хочу. Думаю, проблема понятна.
Ну можно например сделать так: вы определяете сборку в которой описаны ИСКЛЮЧИТЕЛЬНО интерфейсы делегаты и прочие перечисления с аттрибутами. Интерфейсы как те что плагин реализует, так и те, что вы выставляете наружу. Плагины реализует метод типа Initialize(System.IServiceProvider serviceProvider), ну и плагин сам тогда запрашивает те сервисы, которые ему нужны. Либо напрямую инициализируете его теми самыми сервисами которые считаете необходимыми.
Deny everything...
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
ОК.
Код интерфейсной сборки:
using System;
namespace Mutant
{
public interface IInitializable
{
void Initialize(IServiceProvider serviceProvider);
}
public interface IPlugIn: IInitializable
{
void DoIt();
}
public interface IServer
{
void PrintKarrramba();
}
}
Код сервера:
using System;
using System.Reflection;
namespace Mutant
{
public class Server: IServer, IServiceProvider
{
public Server()
{
Assembly assm = Assembly.LoadFrom("PlugIn.dll");
Type plug_in_type = assm.GetType("Mutant.PlugIn");
IPlugIn plug_in = Activator.CreateInstance(plug_in_type) as IPlugIn;
plug_in.Initialize(this);
plug_in.DoIt();
}
private static void Main()
{
Server server = new Server();
}
public void PrintKarrramba()
{
Console.WriteLine("Karrramba");
}
public object GetService(Type serviceType)
{
if (serviceType == typeof(IServer))
{
return this;
}
return null;
}
}
}
Код плагина:
using System;
namespace Mutant
{
public class PlugIn: IPlugIn
{
private IServer server;
public void Initialize(IServiceProvider serviceProvider)
{
server = serviceProvider.GetService(typeof(IServer)) as IServer;
}
public void DoIt()
{
if (server != null)
{
server.PrintKarrramba();
}
}
}
}
Соответственно на интерфейсную сборку ссылаются и сервер и плагин.
Deny everything...
данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение