-
Notifications
You must be signed in to change notification settings - Fork 106
Delegate Plugin Catalog
Delegate Plugin Catalog is part of the Plugin Framework's main package:
Tests: https://github.com/weikio/PluginFramework/blob/master/tests/unit/Weikio.PluginFramework.Tests/DelegateCatalogTests.cs
Delegate Plugin Catalog allows you to use a System.Func or a System.Action as a plugin. Here's a simple example of creating a plugin using an Action:
var catalog = new DelegatePluginCatalog(new Action(() =>
{
Console.WriteLine("Hello from plugin");
}));
await catalog.Initialize();
Here's an example of a Func-based plugin:
var catalog = new DelegatePluginCatalog(new Func<int, Task<bool>>(async i =>
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
Console.WriteLine("Hello from plugin");
return true;
}));
Here's an example code where a plugin catalog is created and initialized and then a plugin instance is created and executed:
var catalog = new DelegatePluginCatalog(new Action(() =>
{
Console.WriteLine("Hello from plugin");
}));
await catalog.Initialize();
var ourPlugin = catalog.Single();
dynamic instance = Activator.CreateInstance(ourPlugin);
instance.Run();
Under the hood the DelegatePluginCatalog creates a wrapper class for the delegate. Developer can control the name of the class and its namespace. The generated class contains a single Run-method which can be used to execute the delegate. Method's name can be also changed.
The Run-method's signature matches the delegate's signature. If you have a Func which takes int and bool as parameters and returns a string, the generated method will look like the following:
public string Run(int x, bool y)
{
...
return "result";
}
DelegatePluginCatalogOptions contains a list of conversion rules which can be used to alter the code generation. These rules can do two things:
- Convert delegate parameters to constructor parameters
- Convert delegate parameters to properties
By default the generated type doesn't have any constructor parameters nor properties. Given the following example delegate from the sample:
var funcWithExternalService = new Func<string, ExternalService, string>((s, service) =>
{
var words = service.GetWords();
s = s + Environment.NewLine + words;
return s;
});
By default the generated output looks like the following:
public class GeneratedType
{
public string Run(string s, ExternalService service)
{
...
}
}
The following conversion rules move all the parameters of type ExternalService as constructor parameters and all the parameters named "s" as public properties:
new DelegateConversionRule(info => info.ParameterType == typeof(ExternalService), nfo => new ParameterConversion() { ToConstructor = true }),
new DelegateConversionRule(info => info.Name == "s", nfo => new ParameterConversion() { ToPublicProperty = true }),
Making the generated output like the following:
public class GeneratedType
{
private ExternalService _service;
public string S { get;set; }
public GeneratedType(ExternalService service)
{
_service = service;
}
public string Run()
{
...
}
}