I'm using dependency injection to register my DbContext in the controller of a ASP.NET MVC Core Application like this:
public void ConfigureServices(IServiceCollection services) {
return new MyContext(connectionString); }
services.AddScoped<IMyContext, MyContext>((serviceProdiver) => {
return new MyContext(Configuration["ConnectionStrings:MyContext"]);
});
services.AddMvc();
}
This works well. But now I want to use Migrations like Add-Migration Initial -Context MyContext
which requires a parameterless constructor. But this would destroy the DI pattern because I would need to fallback to singleton pattern from classic ASP.NET MVC like the following:
public class MyContext:MySqlDbContext, IMyContext {
public MyContext() : base(Startup.Configuration["ConnectionStrings:MyContext"] {
}
}
I like to avoid this to consequently use DI in my new ASP.NET Core project. Is this possible using database-migrations or isn't the migration-tool updated yet for DI so that there is no alternative to use the old singleton pattern here?
Wow, you did very big mistake. You need not to add some your configuration to MyContext, because it's autogenerated file. What have you to do ? You have to add some your configuration file for example RegisterServices or it will be extension. For example
public static class ServiceCollectionExtensions
{
public static IServiceCollection RegisterServices(
this IServiceCollection services)
{
services.AddTransient<ICountryService, CountryService>();
// and a lot more Services
return services;
}
}
And after that you have to Register this your configuration file in ConfigureServices, for example
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.RegisterServices();
}
Finally, you can use Services or Repositories
public class HomeController : Controller
{
private readonly ICountryService _countryService;
public HomeController(ICountryService countryService)
{
_countryService = countryService;
}
// …
}
Or, at the moment new in ASP.NET Core MVC is, that we can also inject this service into a MVC view. The following line defines the injection in a Razor view:
@inject DiViews.Services.ICountryService CountryService;
The first part after the @inject directive defines the interface. The second part is the name of the variable which holds our instance.
To inject a service globally into all Views, add this line to the _ViewImports.cshtml. In a complete new ASP.NET Core project, there is already a global injection defined for ApplicationInsights:
@inject Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration TelemetryConfiguration
We are now able to use the instance in our view:
@if (countryService.All().Any())
{
<ul>
@foreach (var country in CountryService.All().OrderBy(x => x.Name))
{
<p>@country.Name (@country.Code)</p>
}
</ul>
}
We can also use this service to fill select fields with the list of countries:
@Html.DropDownList("Coutries", CountryService.All()
.OrderBy(x => x.Name)
.Select(x => new SelectListItem
{
Text = x.Name,
Value = x.Code
}))
I hope, it was helpful for you