Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement partial methods across multiple assemblies

Tags:

c#

asp.net

In one of the applications I am working on, there are two basic functionalities included: Create and Update.

However, there is a need sometimes to add custom code, so I thought of extending the code by allowing 3rd parties to write and embed their own code:

OnCreating OnCreated OnUpdating OnUpdated

Is there a way to enable the above across multiple assemblies? MEF might help here?

Thank you Regards


Thanks all for your replies.

Having such an interface means each external assembly has to implement that interface as needed. Then, my application's code, needs to loop through the currently running assemblies, detect all classes implementing that interface, and run their methods?

Does MEF fit here? I can export the implementation from external assemblies and import them inside my app?

Thank you Regards

like image 338
Bill Avatar asked Jan 24 '11 13:01

Bill


2 Answers

You can't have partical classes accross assemblies because partial classes are a language feature, and not a CLR feature. The C# compiler merges all the partial classes into one real class, and that single class the the only thing left after compilation.

You have a couple of alternatives:

  1. Offer events
  2. Make the methods virtual and override them
  3. Use an interface

Your problem looks like it fits events best. The user can simply subscribe to them in the other assembly.

like image 95
CodesInChaos Avatar answered Sep 20 '22 13:09

CodesInChaos


Regarding your MEF question, you could probably do something like the following to run methods from an interface:

var catalog = new DirectoryCatalog("bin");
var container = new CompositionContainer(catalog);
container.ComposeParts();

var plugins = container.GetExportedValues<IPlugin>();
foreach (IPlugin plugin in plugins)
{
    plugin.OnCreating();
}

Or create an interface with events as Brian Mains suggested:

public interface IPlugin 
{
    event OnCreatingEventHandler OnCreating;
}

then the above code would be more like:

var catalog = new DirectoryCatalog("bin");
var container = new CompositionContainer(catalog);
container.ComposeParts();

var plugins = container.GetExportedValues<IPlugin>();
foreach (IPlugin plugin in plugins)
{
    plugin.OnCreating += MyOnCreatingHandler;
}

I think I like the latter for the method names you specified. For my plugin work, I've created an interface similar to the following:

public interface IPlugin
{
    void Setup();
    void RegisterEntities();
    void SeedFactoryData();
}

The RegisterEntities() method extends the database schema at runtime, and the SeedFactoryData() method adds any default data (eg. adding default user, pre-population of Cities table, etc.).

like image 29
James Fernandes Avatar answered Sep 24 '22 13:09

James Fernandes