проверьте, содержит ли класс из сборки все методы, как в интерфейсе - PullRequest
2 голосов
/ 21 февраля 2012

У меня есть пользовательская сборка, которая загружается во время выполнения.

На данный момент у меня есть код, который загружает DLL и может создать новый экземпляр объекта и метод andexecute.

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

(я пытаюсь создать подключаемую систему с другим действием, которое можно включить во время выполнения, чтобы обеспечить другое поведение).

где мой код был бы таким: основная программа:

public Interface IArticleManager{
 void SetMenuId(int MenuId);
 void SetMenu(string name);
 void SetContent(string content);
 bool Save();
}

мои библиотеки классов (отключены, вы можете увидеть это из решения)

public class XmlArticle{
    public void SetMenuId(int MenuId){
       //some implementation
     }
     public void SetMenu(string name){
       //some implementation
}
     public void SetContent(string content){
       //some implementation
}
    public bool Save(){
}
}


public class SqlArticle{
    public void SetMenuId(int MenuId){
       //some implementation
     }
     public void SetMenu(string name){
       //some implementation
}
     public void SetContent(string content){
       //some implementation
}
    public bool Save(){
}
}

Ответы [ 4 ]

3 голосов
/ 21 февраля 2012

По сути, перефразируя, вы хотите проверить, определяет ли класс контракт интерфейса, даже если он явно не реализует этот интерфейс?

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

Если вы настаиваете на том, чтобы идти по этому маршруту, однако:

var interfaceType = typeof(IArticleManager);
var targetType = typeof(SqlArticle);
foreach(var member in interfaceType.GetMembers())
{
    var targetMember = targetType.GetMember(member.Name);
    // compare the arguments, generic constraints, etc here
}

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

1 голос
/ 21 февраля 2012

Похоже, вам нужно переместить интерфейс в отдельную сборку, которая содержит только интерфейсы, доступные как для «основной программы», так и для динамически загружаемых библиотек DLL.

Итак, по порядкучтобы создать динамически загружаемую DLL-библиотеку и ожидать, что она будет работать в вашей инфраструктуре, автору сначала нужно обратиться к сборке интерфейса, а затем реализовать предоставленный интерфейс.

1 голос
/ 21 февраля 2012

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

Чтобы проверить, что экземпляр объекта реализует интерфейс, вы:

if (obj is IArticleManager)

, который вернул бы true.

Однако если вы хотите использовать методы интерфейса, то лучше (меньше приведения):

IArticleManager manager = obj as IArticleManager;  
if (manager != null)  
{ do stuff }
0 голосов
/ 21 февраля 2012

А в чем смысл IArticleManager, когда его нельзя использовать нигде?

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

Как и для каждого плагина или другого внешнего кода, вы должны проверять вывод и защищать свое приложение от ошибок (то есть перехватывать и регистрировать исключения плагина). Это также будет обрабатывать недействительные плагины (те, которые не имеют необходимой подписи)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...