tags:

views:

166

answers:

7

I want to add some functionality to every module/plugin written such as:

Author, Company, Date, etc

that represents where it's coming from and who wrote it. Then the programmer could have multiple plugins in a single DLL. How should I implement support for these so I can access them in the main application UI? Generally 1 plugin is a single public class.

Should I use Properties or attributes? Also should I use interfaces?

I want these things to be filled by the programmer, and not make it optional.

+5  A: 

I would use an interface, myself. nice thing is, you can add it to an existing class and not have to do a major re-write of existing code, just add the properties/methods of your interface.

Muad'Dib
Thanks. I can still force them to implement it by adding the interface to a necessary interface for plugins, right?
Joan Venge
yup, that should work w/o any problem
Muad'Dib
A: 

Personally, I would go for attributes, but would assign the value to a backing read-only property in the constructor.

Best of both worlds. :)

leppie
Thanks, why would you use properties in addition?
Joan Venge
Ease of use .
leppie
Thanks, I see :)
Joan Venge
+1  A: 

If you use attributes, that would make it harder for plugin implementers to notice if they forgot to fill in one of the fields. With an abstract property, they would be forced to implement it or face compile errors:

public abstract class PluginBase
{
    protected PluginBase()
    {
    }

    public abstract string Author
    {
        get;
    }

    // ...
}

The only downside is that this kind of information is really metadata, so you could argue that attributes look better from a "semantically correct" perspective.

bobbymcr
+2  A: 

I'd go for attributes, just because it sounds like the items you wish to track don't need to be part of the application, but rather adornments to the code itself.

Also, I think the temptation of programmers to add other junk to this that doesn't really belong would be lesser if it were an attribute.

Aaron Daniels
Yes, true. They will just be visible in the About section of the plugin.
Joan Venge
+2  A: 

I think using an interface is a better approach. Because either way every one who wants to write a plugin should do it based on a contract (implementing an interface or putting some attributes over his class members) so it doesn't matter from the plugin developer point of view , but it would be easier ,more structured (and I think faster) for your program to recognize and utilize an implemented class based on an interface.

Beatles1692
+2  A: 

Since the data is technically metadata about the class, and not actual state required by the plugin, I would use attributes. Attributes are intended to be metadata about the code, which is what you want.

As far as enforcing them, you could have the host application fail to load the plugin if the metadata was missing. That way, the plugin developer would not be able to test the plugin without providing the data. However, you should provide ample documentation so they know what they are missing, or provide detailed errors when you fail to load the plugin.

Most assemblies already have some basic information (Company, Version, etc.) that is set in the AssemblyInfo class. You could also possibly leverage this instead as well.

Also, to prevent the missing data problem, you could use a single PluginAttribute that took all the metadata in as parameters on the property, and require that attribute for your host to load the class. I was initially thinking one attribute per item you wanted to record, but a single attribute would work even better.

NerdFury
Thanks. Can I access AssemblyInfo stuff programmatically? If so that might be just what I need though I have to think whether I need this info per plugin or assembly.
Joan Venge
You can, when you load the assembly to check the classes contained within, you can use reflection to get the assemblies attributes.
NerdFury
Also just saw your last paragraph. Can you please explain it in a little more detail?
Joan Venge
+1  A: 

There are already attributs for that, so why reinvent the wheel?

using System.Reflection;

[assembly: AssemblyTitle("my app")]
[assembly: AssemblyDescription("good app")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("mycorp")]
[assembly: AssemblyProduct("my prod")]
[assembly: AssemblyCopyright("Copyright © me 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("1.0.0.0")]

Per default they are already present in the file AssemblyInfo.cs.

This is the standard way for storing version information and other metadata in assemblies. Maybe there are other Attributes also of interest for you, you also can create your own Attributes for that.

codymanix
Thanks, that's good, but I can only have 1 of these per assembly, right? I might need them per plugin which can be in a single assembly, I will see how to do that one.
Joan Venge
You can create your own Attributes for that and use [AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false)] on the attribute class to specify that it applies to a class and that the same attribute may not be used multiple times per class.
codymanix
Thanks. I meant having potentially multiple ones. So att #1 can be used in plugin 1-5, and att #2 can be used in plugin 6-7 in the same assembly.
Joan Venge
You can have multiple ones - one for each class.
codymanix