Using Cocona with another IoC Container
I am currently designing a console application based on IoC principles. Seeing that Cocona supports proper GetOpt command line parsing, Git-style (sub)-commands and is built with DI in mind makes it seem like a perfect fit for my needs.
My only problem is that, instead of Microsoft.Extensions.DependencyInjection, I'm using DryIoc instead. That library has some nice advanced features, is well documented and is even supposed to perform better than Microsoft's implementation.
I looked into Cocona.Lite and noticed that it too uses a smaller, standalone DI implementation. I was also able to register and inject some services using CoconaLiteAppHostBuilder.ConfigureServices(). Services added this way are independent of my own Container of course.
This got me thinking however: Wouldn't it be possible to adapt Cocona.Lite to use another Container as the source for locating services (those that aren't Cocona internal components at least)?
This could for example be done by allowing a different instance of System.IServiceProvider to be provided when creating an App. Some Containers (like DryIoc and Autofac) even implement this interface natively.
To elaborate, here's a very basic example of what I'm trying to achieve. Check the comments for details:
class Program
{
static void Main(string[] args)
{
// Create a DryIoc container and register services.
// This would happen outside of the Cocona application and also uses some advanced container features like scopes (not shown in this example)
var container = new DryIoc.Container();
container.Register<IMyService, MyService>(Reuse.Singleton);
//...
// Create a Cocona application (Lite)
var app = CoconaLiteApp.Create();
// Here I could normall register services with Cocona itself.
// This is not feasible here because I'm using an existing container...
//app.ConfigureServices(services => services.AddSingleton<IMyService, MyService>());
//TODO: Combine Cocona with the container above...
app.Run<Program>(args);
}
// The service will be injected by Cocona, but would need to be resolved from the existing Container
private readonly IMyService service;
public Program(IMyService service)
{
this.service = service;
}
public void Run([Argument] string name)
{
Console.Out.WriteLine(this.service.Greet(name));
}
}
// Here's the very, very basic service used above.
internal interface IMyService
{
string Greet(string name);
}
internal class MyService : IMyService
{
public string Greet(string name) => $"Hello {name}!";
}
I'm using DryIoc in my project and for this example, but the same scenario should also apply to pretty much every other IoC container out there...
TL;DR: Make it possible to use Cocona's injection features with alternate IoC containers (like DryIoc, AutoFac) instead of just Microsoft.Extensions.DependencyInjection.