Skip to content

Instantly share code, notes, and snippets.

@schotime
Forked from jmarnold/pluginrunner.cs
Created January 8, 2012 05:53
Show Gist options
  • Save schotime/1577402 to your computer and use it in GitHub Desktop.
Save schotime/1577402 to your computer and use it in GitHub Desktop.
Plugin Runner
public interface IActivity
{
void Run();
bool Matches(int i);
}
public class PluginCoordinator
{
private readonly IPluginActivator _activator;
private readonly PluginRunner _pluginRunner;
List<string> _loadedAssemblies = new List<string>();
public PluginCoordinator(IPluginActivator activator, PluginRunner pluginRunner)
{
_activator = activator;
_pluginRunner = pluginRunner;
}
public void Initialise()
{
var dir = new DirectoryInfo("plugins");
foreach (var file in dir.GetFiles("*.dll").Where(x=>!_loadedAssemblies.Any(y=>y == x.FullName)))
{
var assembly = Assembly.LoadFile(file.FullName);
_activator.ActivateFrom(assembly);
_loadedAssemblies.Add(file.FullName);
}
_pluginRunner.Run();
}
}
public class PluginActivator
{
private readonly IContainer _container;
public PluginActivator(IContainer container)
{
_container = container;
}
// call this for each new assembly
public void ActivateFrom(Assembly assembly)
{
_container.Configure(x =>
{
x.Scan(s =>
{
s.Assembly(assembly);
s.AddAllTypesOf<IActivity>();
});
});
}
}
public class PluginRunner
{
private readonly ILogger _logger;
private readonly IEnumerable<IActivity> _activities;
public PluginRunner(ILogger logger, IEnumerable<IActivity> activities)
{
_logger = logger;
_activities = activities;
}
public void Run()
{
//var i = 0;
foreach (var activity in _activities.Where(activity => activity.Matches(1)))
{
activity.Run();
_logger.SetDebug();
}
}
}
@jmarnold
Copy link

jmarnold commented Jan 8, 2012

You don't want that coordinator to be singleton since it's got the runner as a dependency so I'd make the _loadedAssemblies be static

@schotime
Copy link
Author

schotime commented Jan 8, 2012

Yeh agreed. Problem I have now is that the activities passed to the PluginRunner are setup at the start so it doesn't find the new ones. How do I combat this...??? Its something I find always trips me up too.

@jmarnold
Copy link

jmarnold commented Jan 8, 2012

Sorry, I don't think I'm understanding the problem. Can you elaborate?

@schotime
Copy link
Author

schotime commented Jan 8, 2012

When the PluginCoordinator gets instantiated it also instantiates the PluginRunner which obtains all the IActivities. But when I try to add new ones, the IEnumerable dependency has already been setup so it won't include the new ones found.

@jmarnold
Copy link

jmarnold commented Jan 8, 2012

Gotcha. The coordinator shouldn't bother with the runner -- at least not the way it is now. Let's make it a little more real and assume that the coordinator has some sort of file watcher in it, right? If that's the case, then you want the runner. Your best bet is to either: a) delegate out to a factory (i.e., IPluginRunnerFactory) or b) simply depend on Func

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment