views:

180

answers:

6

Hi

what's the recoomended approach in C# when one wants to implement a simple plugin approach?

So basically I have a processing loop that I want different behavior to occrur depending on what the user selected. Let's say there are two places in the processing code for which logic (code)has to be different depending upon user input. For example the user may select either web based or file based upload. So I really kind of want to pass the two specific methods into the processing loop to represent

any suggestions re who to implement things for this here?

Thanks

A: 

Have you looked into Microsoft's Managed Extensibility Framework?

From the intro:

The Managed Extensibility Framework (MEF) is a new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed. If you are building extensible applications, extensible frameworks and application extensions, then MEF is for you.

ChrisF
+2  A: 

Maybe you should see the Inversion of Control Pattern (Dependency Injection) which is basically about resolving the implementation of an interface at runtime (in very few words).

Aggelos Mpimpoudis
A: 

You could use delegates, or partial methods to allow hooking in your code, but these mean that the assembly has to be recompiled.

Philippe
+1  A: 

Other people have mentioned Delegates, and if you're controlling all of the code and the functionality yourself, this is the best approach, however, if you really want a plug-in based system, such that your application exposes some API, and you allow 3rd-party developers to write an assembly (usually a DLL) that will be loaded and the functionality consumed by your application, you can use a number of methods.

The general approach is that your application (the host application) will publish/expose an assembly with specific interfaces. Other developers will write their assemblies and ensure that their classes implement your application's interfaces. The host application will then usually enumerates through a folder that contains the "plug-in" assemblies and finds assemblies that define a class that implements its interface's. The host application will then dynamically load those assemblies and instantiates the classes.

A good tutorial on this general approach can be found here:

Plugin Architecture using C#

The Managed Extensibility Framework is also another option for a general purposes plugin architecture, but may be overkill for what you are trying to achieve.

CraigTP
+2  A: 

Do you really need a (traditional) plugin based solution to this problem? Personally I do not think so, it sounds to me like are trying to over complicate the solution to what is really a simple problem.

The way I would approach this, would be to have a separate service class which is responsible for processing the logic depending on the type of upload. Have an enum to define what type of upload the user has selected, and then instantiate the relevant concrete implementation of the service class to do the processing.

public enum FileUploadType
{
    File,
    Web
}

public interface IProcessingService
{
    void Process();
    object GetResults(); // or whatever you want to do with the results of processing
}

public void Process(FileUploadType fileUploadType)
{
    IProcessingService service;

    switch(type)
    {
     case FileUploadType.File: service = new FileUploadProcessingService(); break;
     case FileUploadType.Web: service = new WebUploadProcessingService(); break;
     default: /* log error */ break;
    }

    service.Process();

    /* do something with results of processing */
}

You could then easily refactor this later on if you then decide you want to start using an IoC container, or introduce a proper plugin mechanism.

sgrassie
Thanks- so this approach doesn't use any delegate correct?
Greg
I think this approach would suit what I'm doing best
Greg
A: 

What's wrong with an if?

Wouldn't be simpler something like that?

if (IsCase1(userInput))
{
   ... do case 1 actions
}
else
{
   ... do case2 actions
}

I wouldn't complicate things more than necessary. The key point here is ¿is it necessary? If you really need passing the functionality as a parameter, I would use the Delegates solution (the next simpler one), and only go for the plugins as the last resort.

Remember the KISS principle!

Juan Calero