Simple package to help route certain commands to functions, similar to routing in ASP.
PM> Install-Package CommandRouter
Or for integration with MVC
PM> Install-Package CommandRouter.Integration.AspNetCore
Add services.AddCommandRouter()
to your Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddCommandRouter();
}
Next create a command. All commands must extend the Command
class.
public class TestCommand : Command
{
[Command("hello")]
public ICommandResult Test()
{
return StringResult("Hello world!");
}
}
All commands must be decorated with the Command
attribute and must also return either ICommandResult
or void
(async
is also supported).
To run a command, call RunAsync
on ICommandRunner
var result = await _commandRunner.RunAsync(command);
The command result is similar to the IActionResult. It has only one method on it
Task ExecuteAsync(Stream resultStream)
resultStream
will be written to when this function is called.
Request level context items can also be passed in the second parameter of RunAsync
await _commandRunner.RunAsync(command, new Dictionary<string, object>
{
{"content", "Hello world!" }
});
These will be available from within the Command
[Command("hello")]
public ICommandResult Test()
{
return StringResult(Context.Items["content"].ToString());
}
By default, parameters are tokenized based on space. Eg command parameter
. Parameters are passed based on the order in the Command action.
The below will return The id is: 88
for the command hello 88
[Command("hello")]
public ICommandResult Test(int id)
{
return StringResult("The id is: " + id);
}
You can add your own parameter converters to support more complex models by implementing IPropertyConverter
public class JsonConverter : IPropertyConverter
{
public bool CanConvert(Type propertyType, object value)
{
throw new NotImplementedException();
}
public object Convert(Type propertyType, object value)
{
throw new NotImplementedException();
}
}
Additional converters can be added to your CommandRouter in the Startup.cs
file
services.AddCommandRouter(options =>
{
options.PropertyConverters.Add(new JsonConverter());
});
If you are using some form of custom DI which doesn't add services into the default IServiceProvider
, you can implement your own ICommandActivator
and register it in the default IServiceProvider
.
public class SimpleInjectorCommandActivator : ICommandActivator
{
private readonly Container _container;
public SimpleInjectorCommandActivator(Container container)
{
_container = container;
}
public object Create(Type type)
{
return _container.GetInstance(type);
}
}
[Route("{command}")]
public async Task<IActionResult> Index(string command)
{
var result = await _commandRunner.RunAsync(command, new Dictionary<string, object>
{
{"content", "Hello world!" }
});
return new CommandRouterResult(result);
}