I'm creating a plugin system for my application and I would like for the plugins to expose a humanly readable name. The application will show a list of available plugins, in this list the name need to be available.
I want to make it very clear for the developers of the plugins what they need to do to make their plugins work.
Currently I'm making the plugin-classes implement an interface and the interface require a property "ConsumerName" to be implemented. However, this requires the main application to create an instance of each plugin, in order to use the CunsumerName property, just to show the list.
public interface IDataConsumer : IDisposable
{
string ConsumerName { get; }
void Consume(DataRowSet rows);
...
}
Is there any way to force the plugins classes to supply meta-data without creating instances of each type?
My fallback plan is to use reflection and some Attribute on each class, but I don't think that Attributes can be forced using interfaces.
No, attributes can't be made part of the contract for an interface. But they can be highly recommended.
What I've done in the past is made an attribute such as:
[AttributeUsage(AttributeTargets.Class)]
public class PluginNameAttribute : Attribute {
public string ConsumerName { get; set; }
}
If a programmer chooses to decorate his class with that attribute, then great. If not, you can fall back on the class name itself:
var consumerName = type.Name;
var nameAttribute = type.GetCustomAttributes(typeof(PluginNameAttribute), true)
.FirstOrDefault() as PluginNameAttribute;
if (nameAttribute != null) {
var attributeName = nameAttribute.ConsumerName;
if (!string.IsNullOrEmpty(attributeName)) {
consumerName = attributeName;
}
}
It shouldn't be too much to ask of plugin developers to use the attribute if it's documented that they should do so.
Normally I would say "no there is not". That's because there are two mechanisms that allow information to be pulled out of types without requiring an instance to be created: static
members and attributes. Since there is no overlap between these mechanisms and interfaces, you cannot satisfy all of your stated requirements at the same time.
However, what's wrong with the attribute-based solution? Certainly you cannot force the presence of the attribute on pain of a failed compile, but you can do that when loading the plugin (or even earlier).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With