Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing other attributes to metadata using C# MEF

Tags:

c#

mef

Using some tutorials on the web, I created a metadata class for my needs using the MEF in C#

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class ActionMetadataAttribute : Attribute
{
    public bool HasSettingsDialog { get; set; }
    public bool UseThreadedProcessing { get; set; }
}

public interface IActionMetadata
{
    [DefaultValue(false)]
    bool HasSettingsDialog { get; }

    [DefaultValue(false)]
    bool UseThreadedProcessing { get; }
}

I've got different kind of plugin types, so there is e. g. IHandlerMetadata and HandlerMetadataAttribute. Now I load it via the Lazy helper to allow strictly typed metadata.

[ImportMany(typeof(IActionPlugin))]
private IEnumerable<Lazy<IActionPlugin, IActionMetadata>> _plugins = null;

public ActionManager()
{
    var catalog = new DirectoryCatalog(".");
    var container = new CompositionContainer(catalog);
    container.ComposeParts(this);

    foreach (var contract in _plugins)
    {
        Debug.WriteLine(contract.Metadata.HasSettingsDialog);
    }
}

Works perfectly. Now, I also like to have some information about the plugins. So I've created an PluginInformationAttribute.

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class PluginInformationAttribute : Attribute
{
    public string Name { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public string Url { get; set; }
    public string Contact { get; set; }
    public string Description { get; set; }
    public Version Version { get; set; }
}

The question is now: how can I access this attribute for example in the for loop in the above code snippet? Is there any way or is my design wrong? I don't want to include the PluginInformation stuff to IActionMetadata because I'd like to use it on different types of plugins, e. g. on the IHandlerMetadata.

like image 816
The Wavelength Avatar asked Aug 10 '14 14:08

The Wavelength


Video Answer


1 Answers

If you specify the type of your exporting class as a property of ActionMetadataAttribute, then you can access every attribute of the class by reflection with GetCustomAttributes method

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class ActionMetadataAttribute : Attribute
{
    public bool HasSettingsDialog { get; set; }
    public bool UseThreadedProcessing { get; set; }
    public Type ClassType { get; set; }
}

var attributes = contract.Metadata.ClassType.GetCustomAttributes(typeof(PluginInformationAttribute), true)
like image 102
Giuseppe Panzuto Avatar answered Sep 20 '22 18:09

Giuseppe Panzuto