Указание пользовательских атрибутов .Net, которые находятся в другой сборке. - PullRequest
0 голосов
/ 25 июня 2011

Мои вопросы:

  • Это выглядит «правильно»? Или я упускаю что-то фундаментальное?
  • Поскольку у меня есть ссылка на PluginCo.Load.dll, в которой содержится пользовательский атрибут, который мне нужно указать в своем плагине, это возможно, верно?

Я пытаюсь создать .Net DLL для загрузки в архитектуру плагина. Для того, чтобы он загружался в хост-приложении, класс и метод моего плагина должны иметь определенный указанный атрибут. Этот пользовательский атрибут реализован в отдельной DLL для плагина.

Код моего плагина, который я пытаюсь написать, заключается в том, что я считаю проблемой. Его СЛЕДУЕТ загружать в инфраструктуру плагинов, поскольку он указывает атрибут CreatedByPluginCo для класса:

using System.Windows.Forms;
using PluginCo.Load;

namespace _test2
{

    [CreatedByPluginCo]
    public class Class1
    {
        [CreatedByPluginCo]
        public static void Test()
        {
            MessageBox.Show("If you see this it worked!");
        }
    }

Вот как выглядит код в PluginCo.Load.dll:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
public class CreatedByPluginCoAttribute : Attribute
{
    // Fields
    private string _stringComment = string.Empty;

    // Properties
    public string Comment
    {
        get
        {
            return this._stringComment;
        }
        set
        {
            this._stringComment = value;
        }
    }
}

Для метода проверки наличия атрибута CreatedByPluginCo в моей сборке (которую я надеюсь в конечном итоге загрузить как плагин) я собрал этот метод вместе в небольшом приложении (требуется Reflection):

public static Attribute GetCreatedByPluginCoAttribute(Attribute[] attributes)
{
    for (int i = 0; i < attributes.Length; i++)
    {
        if (attributes[i].GetType().Name.CompareTo(typeof(CreatedByPluginCoAttribute).Name) == 0)
        {
            return attributes[i];
        }
    }
    return null;
}

и проверьте, возвращает ли это значение null:

if (GetCreatedByPluginCoAttribute(Attribute.GetCustomAttributes(Assembly.LoadFrom(fileName))) == null)

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

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

Любое понимание приветствуется! Даже если это просто «странно, это выглядит правильно для меня», это поможет моему здравомыслию.

1 Ответ

1 голос
/ 25 июня 2011

Вызываемая GetCustomAttributes перегрузка возвращает настраиваемые атрибуты, которые применяются на уровне сборки, а не типы или методы.

Вам нужно будет перечислить открытые типы в сборке, а затем проверить каждый из них, чтобы выяснить, применяется ли к нему ваш атрибут.

И чтобы ответить на ваш другой вопрос: Нет, в том, что вы делаете, нет ничего принципиально неправильного (, но слышали ли вы о MEF? Возможно, вы избавите себя от некоторых проблем).

...