Как создать атрибут Icon для плагина в C #? - PullRequest
2 голосов
/ 18 августа 2010

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

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

[Client("Heroes of Newerth", "Heroes of Newerth Chat Client", "hon_16.png")]

С этим моим хост-приложением можно прочитать metainfo плагина / клиента без фактического создания его экземпляра, но я застрял с иконкой.

Как и в предыдущем примереНапример, клиент может передать имя файла растрового изображения, и в моей реализации атрибутов я могу обработать его следующим образом:

[AttributeUsage(AttributeTargets.Class)]
public class ClientAttribute : Attribute
{
    private string _name;
    private string _description;
    private Bitmap _icon;

    public string Name { get { return this._name; } }
    public string Description { get { return this._description; } }
    public Bitmap Icon { get { return this._icon; } }

    public ClientAttribute(string Name, string Description, string IconFile = null)
    {            
        this._name = Name;
        this._description = Description;
        this._icon = new Bitmap(IconFile);
    }
}

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

Ответы [ 3 ]

2 голосов
/ 18 августа 2010

Вы можете добавить их к ресурсам, а затем получить доступ к ресурсам из пользовательского атрибута. Однако вам нужна ссылка на сборку плагина, поэтому вы не можете сделать это в конструкторе. Я бы сделал это так:

[AttributeUsage(AttributeTargets.Class)]
public class ClientAttribute : Attribute
{
    private string _name;
    private string _description;
    private string _resourceName;
    private Bitmap _icon;

    public string Name { get { return this._name; } }
    public string Description { get { return this._description; } }
    public Bitmap Icon { get { return this._icon; } }

    public ClientAttribute(string name, string description, string resourceName = null)
    {
        _name = name;
        _description = description;
        _resourceName = resourceName;
    }

    public void ResolveResource(Assembly assembly)
    {
        if (assembly != null && _resourceName != null)
        {
            var stream = assembly.GetManifestResourceStream(_resourceName);
            if (stream != null)
                _icon = new Bitmap(stream);
        }
    }
}

Конечно, это означает, что при первом получении пользовательского атрибута свойство Icon будет возвращать ноль до тех пор, пока вы не вызовете Resolve с правильной сборкой. Я написал это так, чтобы он остался нулевым, если есть проблемы; вам нужно решить, хотите ли вы выдавать исключения. В частности, возможно, получатель свойства Icon должен выдать исключение, когда _icon имеет значение NULL, но _resourceName нет, потому что тогда это означает, что Resolve не был вызван или возникла проблема. (Вы все равно должны знать, что даже Resolve может бросить, потому что GetManifestResourceStream или конструктор Bitmap может бросить.)

0 голосов
/ 18 августа 2010

Благодаря Тимви, вот моя последняя реализация;

    internal void ResolveResources(Assembly _assembly)
    {
        if (_assembly != null && this._icon_name != null)
        {                   
            var stream = _assembly.GetManifestResourceStream(string.Format("{0}.Resources.{1}",_assembly.GetName().Name,this._icon_name));
            if (stream != null) this._icon = new Bitmap(stream);
        }
    }

И в моем классе PluginInfo я вызываю распознаватель;

            else if(t.IsSubclassOf(typeof(Client)))
            {
                object[] _attr = t.GetCustomAttributes(typeof(ClientAttribute), true);
                (_attr[0] as ClientAttribute).ResolveResources(this._assembly);
            }
0 голосов
/ 18 августа 2010

не может добавить их к ресурсам

Почему бы и нет?Вы можете определить IconFile как имя ресурса в той же сборке, что и плагин.Затем, получив Assembly, содержащий плагин, вызовите assembly.GetManifestResourceStream и передайте этот поток конструктору Bitmap.

...