First, to answer your question "can I use a configuration file", the answer is emphatically "yes". Why shouldn't you is answered later, but for now, here's a poor man's version of how you might do this by adding to your appsettings.json file. Note that this code is not optimal, but is designed to show you how you could implement this solution.
Let's start with some classes to hold the data:
public class ServicesConfiguration
{
public IEnumerable<ServiceItem> Singleton { get; set; }
public IEnumerable<ServiceItem> Transient { get; set; }
}
public class ServiceItem
{
public string Service { get; set; }
public string Implementation { get; set; }
}
Now add a section to your JSON file, you may even want to keep this file external to the main config, but that's an implementation detail I will leave up to you:
{
//snip main config....
"Services" : {
"Singleton": [
{
"Service": "YourNamespace.IFoo1, YourNamespace",
"Implementation": "YourNamespace.Foo1, YourNamespace"
},
{
"Service": "YourNamespace.IFoo2, YourNamespace",
"Implementation": "YourNamespace.Foo2, YourNamespace"
}
],
"Transient": [
{
"Service": "YourNamespace.IBar1, YourNamespace",
"Implementation": "YourNamespace.Bar1, YourNamespace"
}
]
}
}
And now an extension method to configure it all:
public static IServiceCollection AddFromConfigurationFile(this IServiceCollection services,
IConfigurationSection configuration)
{
var servicesConfiguration = configuration.Get<ServicesConfiguration>();
foreach(var service in servicesConfiguration.Singleton)
{
services.AddSingleton(Type.GetType(service.Service), Type.GetType(service.Implementation));
}
foreach(var service in servicesConfiguration.Transient)
{
services.AddTransient(Type.GetType(service.Service), Type.GetType(service.Implementation));
}
//Other scopes here...
return services;
}
And call it in ConifigureServices like this:
services.AddFromConfigurationFile(Configuration.GetSection("Services"));
So, nice and simple right? Why shouldn't you do this? A few ideas off the top of my head:
- Why change how almost all DI implementations work? If it ain't broke, why fix it? Just because you are used to a particular method, doesn't mean it's a good idea.
- Type safety: You lose compile time checking of the types you specify in the configuration file.
- Security: Having this in a config file would let someone change the implementation to a class of their own choice.
I'm sure there are more, but... it's your app!