Im making fixture
to my tests
.
In my FixtureFactory
im making my own ServiceCollection
:
private static ServiceCollection CreateServiceCollection()
{
var services = new ServiceCollection();
services.AddScoped<IConfiguration>();
services.AddScoped<ITokenService, TokenService>();
services.AddDbContext<TaskManagerDbContext>(o => o.UseInMemoryDatabase(Guid.NewGuid().ToString()));
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireDigit = false;
options.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<TaskManagerDbContext>();
return services;
}
Then, im getting this services
from scope
:
var services = CreateServiceCollection().BuildServiceProvider().CreateScope();
var context = services.ServiceProvider.GetRequiredService<TaskManagerDbContext>();
var userManager = services.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = services.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var signInManager = services.ServiceProvider.GetRequiredService<SignInManager<ApplicationUser>>();
var tokenService = services.ServiceProvider.GetRequiredService<TokenService>();
The problem starts when i added TokenService
to my ServiceCollection
.
Constructor, of TokenService
looks like this:
private readonly IConfiguration configuration;
private readonly UserManager<ApplicationUser> userManager;
public TokenService(IConfiguration configuration, UserManager<ApplicationUser> userManager)
{
this.configuration = configuration;
this.userManager = userManager;
}
It works great when i launch my Core
app, but wont work from ServiceCollection
that i mentioned above.
In Tests, i started to get this error:
Message: System.AggregateException : One or more errors occurred. (Cannot instantiate implementation type 'Microsoft.Extensions.Configuration.IConfiguration' for service type 'Microsoft.Extensions.Configuration.IConfiguration'.) (The following constructor parameters did not have matching fixture data: ServicesFixture fixture) ---- System.ArgumentException : Cannot instantiate implementation type 'Microsoft.Extensions.Configuration.IConfiguration' for service type 'Microsoft.Extensions.Configuration.IConfiguration'. ---- The following constructor parameters did not have matching fixture data: ServicesFixture fixture
This error started to show when i added services.AddScoped<IConfiguration>();
to my ServiceCollection
and when i started to get required service TokenService
.
My question is, how to register properly Configuration
that im using in Service
?
Im using Configuration
to get items from settings.json
.
EDIT:
My fixture
and sample test class:
public class ServicesFixture
{
public TaskManagerDbContext Context { get; private set; }
public UserManager<ApplicationUser> UserManager { get; private set; }
public RoleManager<IdentityRole> RoleManager { get; private set; }
public SignInManager<ApplicationUser> SignInManager { get; private set; }
public TokenService TokenService { get; private set; }
public ServicesFixture()
{
var servicesModel = ServicesFactory.CreateProperServices();
this.Context = servicesModel.Context;
this.UserManager = servicesModel.UserManager;
this.RoleManager = servicesModel.RoleManager;
this.SignInManager = servicesModel.SignInManager;
this.TokenService = servicesModel.TokenService;
}
[CollectionDefinition("ServicesTestCollection")]
public class QueryCollection : ICollectionFixture<ServicesFixture>
{
}
}
Tests:
[Collection("ServicesTestCollection")]
public class CreateProjectCommandTests
{
private readonly TaskManagerDbContext context;
public CreateProjectCommandTests(ServicesFixture fixture)
{
this.context = fixture.Context;
}
}
EDIT2
When i delete AddScoped<IConfiguration>();
from my collection and run tests, i get this error:
Message: System.AggregateException : One or more errors occurred. (No service for type 'TaskManager.Infrastructure.Implementations.TokenService' has been registered.) (The following constructor parameters did not have matching fixture data: ServicesFixture fixture) ---- System.InvalidOperationException : No service for type 'TaskManager.Infrastructure.Implementations.TokenService' has been registered. ---- The following constructor parameters did not have matching fixture data: ServicesFixture fixture
The IConfiguration is an interface for . Net Core 2.0. The IConfiguration interface need to be injected as dependency in the Controller and then later used throughout the Controller. The IConfiguration interface is used to read Settings and Connection Strings from AppSettings. json file.
IOptions is singleton and hence can be used to read configuration data within any service lifetime. Being singleton, it cannot read changes to the configuration data after the app has started. Run the app and hit the controller action. You should be able to see the values being fetched from the configuration file.
IOptionsMonitor is a Singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies.
How do we get an instance of the IConfiguration service? Like this: // Add services to the container. In this way, the configuration variable is of type IConfiguration. And so we can get a value from a configuration provider: And that’s it!
Had to call .ImplementationFactory (null). Works but is rather dirty of course. To get IConfiguration from IServiceCollection why not just resolve the dependency?: IConfiguration configuration = services.BuildServiceProvider ().GetService<IConfiguration> ();
return serviceCollection. BuildServiceProvider (); Add a new file called appsettings.json to test the that json config providers are working fine. In the file add the following: In the Main method we setup everything. Main should look like this: IConfiguration configuration = serviceProvider. GetService < IConfiguration > ();
To offer using a service in both ways – using the configuration values from configuration files, and passing it directly with the options, you can create both versions of the extension methods AddGreetingService, the one from the previous article and this one. Defining a Configuration File The sample code uses a JSON configuration file.
You added IConfiguration
with no implementation.
In startup.cs the framework would have created an implementation behind the scenes and added it. You will have to do the same using ConfigurationBuilder
var builder = new ConfigurationBuilder()
//.SetBasePath("path here") //<--You would need to set the path
.AddJsonFile("appsettings.json"); //or what ever file you have the settings
IConfiguration configuration = builder.Build();
services.AddScoped<IConfiguration>(_ => configuration);
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With