I'm creating a CLI application that accepts a string as an input and calls a specific method from a list of plugins. The methods that can be invoked can have multiple, none or optional parameters. With MEF, the exports must have the same method signatures. I want the people that will implement the methods to provide only the necessary code and not deal so much with the integration.
The approach I thought of was using both reflection and MEF. Instead of metadata, I'll have the method name, paramtypes and required number of params as the contract. The main application will then invoke the method using the function name provided. I will need to validate the parameters first in the main app before invoking any method.
My question is, Which is the proper way to do this? Please see code:
Original approach
public interface ICommand
{
(bool, IEnumerable<string>) Execute(object[] args);
}
public interface ICommandMetadata
{
string Name { get; }
Type[] ParamTypes { get; }
int RequiredParams { get; }
}
[Export(typeof(ICommand))]
[ExportMetadata("Name", "CustomImpl")]
[ExportMetadata("ParamTypes", new Type[]{ typeof(string), typeof(double) })]
[ExportMetadata("RequiredParams", 1)]
public class CustomImplementation : ICommand
{
public (bool, IEnumerable<string>) Execute(object[] args)
{
var result = MainImplementation(args[0].ToString(), (double)args[1]);
return (true, new List<string> { $"Result: {result}" });
}
private int MainImplementation(string strA, double douB = 5)
{
return strA.Length + (int)douB;
}
}
If both Reflection + MEF approach, I'm thinking like this:
public interface ICommand
{
string FunctionName { get; }
Type[] ParamTypes { get; }
int RequiredParams { get; }
}
[Export(typeof(ICommand))]
public class CustomImplementation : ICommand
{
public string FunctionName { get { return "MainImplementation"; } }
public Type[] ParamTypes { get { return new Type[] { typeof(string), typeof(double) }; } }
public int RequiredParams { get { return 1; } }
private (bool, IEnumerable<string>) MainImplementation(string strA, double douB = 5)
{
return (true, new List<string> { $"Result: {strA.Length + (int)douB}" });
}
}
Aucun commentaire:
Enregistrer un commentaire