System.InvalidOperationException: The current type, Microsoft.Extensions.Configuration.IConfiguration, is an interface and cannot be constructed. Are you missing a type mapping?
I am using unity with .NET Core, and the error above is being given at this line:
container.RegisterInstance<IServiceA>(IoC.Resolve<IServiceB>());
IServiceB is registered as such:
container.RegisterType<IServiceB, ServiceA>(new ContainerControlledLifetimeManager());
I have a class ServiceA that implements IService B as follows.
public class ServiceA : IServiceB
{
private IConfiguration _configuration;
public ServiceA(IConfiguration configuration): base(configReader)
{
_configuration = configuration;
}
public string someVariable => _configuration.GetSection("Section").GetSection("WantedKey").Value;
...
}
I am using Microsoft.Extensions.Configuration.IConfiguration for the Configuration.
So I do not know how to map it because I am getting it from Microsoft.Extensions.Configuration.IConfiguration.
What am I doing wrong? How can I solve it?
Assuming a file like config.json
{
"Section" : {
"WantedKey" : "WantedValue"
}
}
You would first need to build a configuration instance
IConfiguration config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("config.json", optional: true, reloadOnChange: true);
.Build();
And register that with the container
container.RegisterInstance<IConfiguration>(config);
In order for IConfiguration
to be available to be resolved.
Now ideally you really shouldn't be passing IConfiguration
around for injection. It is usually accessed at the composition root to get settings for other dependencies. Try to avoid coupling to external framework dependencies.
In this case you would want to create a strong type to hold the desired settings
public class MySetting {
public string WantedKey { get; set; }
}
And populate an instance of it from configuration
MySetting setting = config.GetSection("Section").Get<MySetting>();
You would register that with the container
container.RegisterInstance<MySetting>(setting);
and have that injected into dependents
public class ServiceA : IServiceB {
private readonly MySetting setting;
public ServiceA(MySetting setting) {
this.setting = setting;
}
public string someVariable => setting.WantedKey;
//...
}
Reference Configuration in ASP.NET Core