CodeButcher

I am working on a .net program.
I want to give users the ability to download add-on's that affect how the program works - new functionality, expanded functionality, that type of stuff.

I just don't know how to get the program to detect the new add-ons and run them appropriately.

I've google for add-on tutorials but I can find a thing. Can someone point me in the right direction or such a tutorial
-thanks.



Re: Visual C# General creating add-on to my own program: tutorials

Derek Smyth

Hi

I think ClickOnce Deployment would help you out here. ClickOnce lets users download and install the application over the wire. You publish the software with a certain version and when the version changes then the software can automatically update itself. In your case publishing an Addin will increment the version number indicating to the software that there are new files to download. The software doesn't have to automatically update, or automatically install all the application/addin files, you have full control through an API.

The good thing is you can group downloadable and installable files and then download them on demand using the API, so for example you could build a browser for the addins and let the user specify which ones to download. Have a look at the ApplicationDeployment class it has the methods to do this, and also have a search for ClickOnce deployment.

That might work, sorry thats not quite a tutorial, but I think ClickOnce would be a good place to start.

If you need any more info then let me know.




Re: Visual C# General creating add-on to my own program: tutorials

A Million Lemmings

If you really do mean plug-ins in the sense of things that someone else could (possibly) write to extend your application, then you will need to design it in to your application. Create some kind of public interface that specifies the plug-ins that you will allow, and then this interface is what other people will have to implement.

So, for example,

public interface IPlugin

{

void DoSomeStuff();

}

Then someone might create a plugin

public class MySnazzyPlugin : IPlugin

{

...

}

These plug-ins that are written would then be packaged up in assemblies and distributed as needed.

You would then have to have some code that will look in a specific location (plugin directory ) and then grab all the assemblies that are in there and, using reflection, scan each of the classes to see if they implement the plugin interface. If they do, then you can add them to your list of plugins.

This is a very quick overview of the kind of thing you would need to do (if this is what you are after). This would mean that you could write the core application, and then if any extra functionality is to be added at a later date (either by you or by third parties), then you wouldn't need to re-build and re-distribute your core application.

Hope this helps.





Re: Visual C# General creating add-on to my own program: tutorials

Derek Smyth

Hi,

Nothing wrong with a million lemmings answer, it's exactly how you'd do it, but but but.... Visual Studio 2008 and .NET v3.5 has a new Plugin API. So the question is, is it worth doing your own implementation (which means other developers need to learn it) or do you use the new Plugin API in the next release of .NET (which means you'll need to delay development until a) you've learned the new API good enough to b) wait and code it up).

Just food for thought.






Re: Visual C# General creating add-on to my own program: tutorials

A Million Lemmings

Yes, Derek, very true. I just assumed that it wouldn't be done with an older version of .net. But yes, if you are going to go with the latest version, then use the framework that is provided - I'm sure Microsoft put a lot more effort into developing it than you could!

Cheers.





Re: Visual C# General creating add-on to my own program: tutorials

A Million Lemmings

Sorry, obviously I mean "I just assumed that it WOULD be done with an older version of .net"...... Ooops.





Re: Visual C# General creating add-on to my own program: tutorials

CodeButcher

Thansk to everyone on this thread!

A plugin API in the next .net version sounds great but for now, I'm confortable with .net 2005. Sometimes a guy just has to draw a line at which version of .net he'll use for a while!

I did find two tutorials for plugins - turns out googling for "addon" was the wrong term.

Here are the two.

The first was terrific at explaining interfacing with a plugin and building a simple plugin.

http://www.scratchprojects.com/2006/03/building_a_plugin_architecture_p01.php

The second was good at user control plugins.

http://www.codeproject.com/csharp/PluginsInCSharp.asp

Finally, there was a great article here on delegates and callbacks.

http://www.vbcity.com/forums/faq.asp fid=15&cat=Object+Oriented+Design&#TID110013

I was able to create a host, interface, and plug that was able to accept data as well as return it. Of course next this the planning phase of what data to expose to plug-ins so it's consistant and "standard" for the plug-in design. But now that I understand the coding, I'm more at ease.

thanks again.





Re: Visual C# General creating add-on to my own program: tutorials

Derek Smyth

Hi,

There is something else you should look into CodeButcher and thats the Command design pattern. This is a pattern that lets you build a class that performs a task. Like for example a class that does FileOpen or a class that does FormatText for example, the class is a command. The good thing about Commands are you generally design them to have a single Execute method, and each class/command has this Execute method.

This is ideal for plugins as it allows you to treat all plugins the same way, a plugin is a command that is performed in your application. I haven't looked at the links to see if they explicitly mention the Command design pattern but they will implicitly follow the pattern. It would be worth your while having a look for information on this, all the information I have is on ye olde paper.

Actually I have an example application that demonstrates the idea of commands as plugins.

I'll upload it later and post the link.

A million lemmings, I really don't like adding comments to other peoples posts especially when they are new to the forums and when they post pretty decent advice. Can't help feel like I'm trying to please my ego. I've looking at the Plugin API and on first look it is obviously trying to be everything to everyone and is therefore really quite powerful and far more complex than a custom solution. I think it's a good move for CodeButcher to follow your advice and implement his own, both have their advantages both have their disadvantages.

The biggest problem with plugins I've came across is passing data from the application to the plugin in a universal way thats future proof enough for new plugins to use. It's easy for a text editor, pass the text, but for other applications it's not so easy. CodeButcher this is where you need to give some thought... how to package your applications data so that plugins can use it, if you can work out a way to do this, and do it in way that can never change, then your pretty much sorted.






Re: Visual C# General creating add-on to my own program: tutorials

CodeButcher

"The biggest problem with plugins I've came across is passing data from the application to the plugin in a universal way thats future proof enough for new plugins to use. It's easy for a text editor, pass the text, but for other applications it's not so easy. CodeButcher this is where you need to give some thought... how to package your applications data so that plugins can use it, if you can work out a way to do this, and do it in way that can never change, then your pretty much sorted."

That's the portion I'm working on now. My first stab was creating properties in the plugin that would be populated such as (warning, pseudo-code on the horizon):

Plugin MyPlugin = new Plugin;

MyPlugin.ImportantData = "this is host data";

But that didn't work.

then I tried passing it as a parameter to the plugin Initialization.:

newPlugin.Instance.Initialize(ImportantData);

This works but I'm not convinced it's the best way.

What I'd like to do is when I call a plugin, pass it 3-4 values such as the data the plugin would manipulate and a couple of smaller pieces of information. So regardless if the plug needed it, it would become available.

It also seems that I should be able to write to an interface class that expands the base interface so I could have 4 plugins that use the basic passed values and then have, say, 3 new plugins that use the base interface + an expanded one to get other exposed info just for those "speciality" plugins.

Such as:

namespace PluginInterface

{

public interface IPlugin

{

...

}

public interface IPassHost : IPlugin

{

void PageData(string toPageData);

void URL(string toURL);

}

}

I haven't got that to work yet.

On another note, thanks for the Command desgin pattern information. I'll look that up. Sounds exactly what I would need for my particular scenario.





Re: Visual C# General creating add-on to my own program: tutorials

CodeButcher

I did get the ability to pass data working as I moved the :

void PageData(string toPageData);

void URL(string toURL);

up into the public interface IPlugin section.





Re: Visual C# General creating add-on to my own program: tutorials

Derek Smyth

Hi,

Heres the link, it's just another example done a while ago and doesn't do much, might be useful, might not. Never initally clocked that you wanted info on creating the plugin, thought you had that and looking for some way to deploy them.

ReflectionPlugin.zip

You know what might be a good idea. Passing XML data to your plugins. The idea would be that each plugin would expect some XML data which it can parse using XPath queries. If you design your plugins to work that way then you can represent the whole applications data as an XML document and send that to the plugins.

That would be universal enough and has a certain amount of future proofing. You could add new data to the XML document as your application expands but as long as you keep the previous XML structure the same (or within the same namespace) then older plugins will still work. You could create a XSD schema that plugin developers can use to know the structure of the data.

Should of thought of that ages, and I mean ages, ago. Yeah pass the plugins an XML document that represents the applications data, query the data in the plugins using XPath expressions, and use namespaces for versioning.






Re: Visual C# General creating add-on to my own program: tutorials

A Million Lemmings

Some good advice and information in these posts. I'll add another couple of comments....

For me, I would tend to avoid using an XML document to pass around the data. I think if you have specific portions of your application that will allow plug-ins, then these should be well-defined interfaces for the functionality.

For example, if you were creating a music playing application that allowed plug-ins, you might have a plug-ins for audio output. This might be an IAudioOutput interface that just has a method of ProcessData(IAudioData data). In this instance, you know exactly what the data is available (IAudioData) and the application will provide just that information as that is all that is important at that time. There is no need for the AudioOutput plug-in to know anything else about the system other than the data which is important for it to process. And I only like to use XML for passing data in and out of a system (Ok, so the plug-in could be thought of as "outside the system", but I would argue that once a plug-in is loaded, then it becomes part of the "system"), or communicating between two completely separate systems, but I think the overhead involved with parsing and extracting the information for something internal to the system is unnecessary when you could just pass some good ol' objects around.

But hey, there's more than one way to solve most problems so it comes down to personal choice and picking whatever you feel is right.

Good luck.





Re: Visual C# General creating add-on to my own program: tutorials

Derek Smyth

Hi.

After reading the above I'd have to disagree with myself and not suggest the XML approach, I think million lemmings has a much better idea. I suppose it's like splitting your application into different conceptual areas (features) and then deciding on which area (feature) can support a plugin. Once you know the areas (features) you can tailor the type of data needed for a plugin to extend an area (feature). That is excellent.

I had always tried to make plugins just support the whole application rather than just a single part of it, this will be why I've always had problems working out how to pass data to the plugin, I was trying to pass everything in the application. This is a much better idea than passing XML.

Some very good information all round here.






Re: Visual C# General creating add-on to my own program: tutorials

CodeButcher

You've both been very helpful. Code and comments!

Point of confusion.

If I wanted multiple interfaces, using the music player as an example, would I create multiple interfaces or create one interface with different areas of exposure I've tried the later with no luck. So would I create more than one interface file





Re: Visual C# General creating add-on to my own program: tutorials

A Million Lemmings

Glad it's being helpful!

Yes, you would create an interface for each area that you would want a plug-in for. So, using the previous example, I would suggest

you might have an interface:

Code Block

public interface IAudioOutput

{

void PlayAudioData(IAudioData data);

}

This interface might be implemented by different plug-ins to output the audio in different ways (one might be to the soundcard, one to a wav file, etc).

Then you might have another area of the application that is for playlists. You would then create another interface

Code Block

public interface IPlaylistSorter

{

IPlaylist SortPlayList(IPlaylist unsortedPlaylist);

}

This could then have different implementations that sort the unsorted list in various ways (by artist, alphabetically, some other methods).

Then, in your application, in the area of code that displays the playlists, you would get the plug-in selected to be the sorter (it probably wouldn't make sense to have more than one) and create an instance of it and call the SortPlayList method passing the unsorted playlist. Of course, all your code would know is that you were calling a SortPlayList method on an interface of IPlayList. The actual implementation is dependant on the plug-in implementations that are available.

You may have an area of code that needs to call many plug-ins (a graphics processing app, for example). In this case, the code would just iterate through all the plug-ins in a certain location. But again, it would just look for the ones that implement a specific interface. When you add new areas of functionality and then new plug-in possibilities, just add a new interface that defines the methods that your app will call on the implementations and what data you will provide and what you expect back.

I realise the example couple of plug-in interfaces I made up here are trivial and probably not very sensible, but I can't think of anything else at the moment! But hopefully you get the idea.

Hope this helps

If you have any more questions, then this is the place to ask them!