This section adds in the remaining services into the default dependency injection container.
- [Instructor] The final configuration step that we need to talk about is dependency injection. Dependency injection is now a first class citizen with ASP.NET Core. Granted, it's always been available with ASP.MVC, but you had to essentially bolt it on yourself. Now it is built-in. Constructor injection is a default mechanism, and there are many built-in services available, for example, creating entity framework DB context classes.
You can also register your own custom interfaces and there's three standard ways of doing that, transient, scoped, and singleton. So transient gets instantiated for every object that needs it. So you must think about that from a performance standpoint. Scoped is once per request, and singleton, as its name implies, gets instantiated as a singleton across the application. It is important to note that you don't need to actually implement the singleton pattern in something that is scoped as a singleton.
The DI container takes care of that. The dependency injection container handles disposing of objects where it is controlling their lifetime. You say that affect how we coded the dispose method in our repository. Back in the startup.cs class, let's go to the configure services and let's add a singleton for the configuration. So services.add, singleton, and the construct we're going to use here is to just pull in its own reference of the configuration that was built in the constructor into the dependency injection container.
So we don't need to recreate the configuration if we need it, we can just pass in an instance of I configuration root. Now after configuring the MVC core, we want to add in the DB context, and this is one of those built-in services that you can use with the built-in DI container. So it's services.AddDbContext. It is of type store context.
And then we want to configure some options. And the first is to use SQL server and then we need to get the connection string. So we use that configuration object. And there are some helper methods, as long as you use the same naming convention, you can use get connection string and the connection string is named SpyStore.
If you change those values, then you'll need to update that line of code. And then, we'll use sqlOptions and that's sqlOptions.EnableRetryOnFailure. And I have one too many parenthesis here.
And there we go. Now we have to add in our product repo and shopping cart repo. So we say services dot, and we want these to be scoped, so AddScoped, and we tell it that anytime there's a request for an IProductRepo, and we'll have to add in a using for SpyStoreDAL.Repos.Interfaces, that we want to actually create an instance of ProductRepo.
And then we'll have to add any using for SpyStoreDAL.Repos. So just to confirm those using statements. Line 15 and 16, SpyStoreDAL.Repos and SpyStoreDAL.Repos.Interfaces. And then the final service that we will add is another scoped, and this is for the IShoppingCartRepo and we want it to create an instance of ShoppingCartRepo.
So anywhere within the ASP.MVC project and any of the assemblies referenced by that, if there is a constructor looking for an IProductRepo or an IShoppingCartRepo, the dependency injection framework will take care of instantiating that for us. Down here in the configure method, we want to do one more thing. We want to call the initializer to put data in the database if we are in development.
Since it is a flush and fill, you certainly wouldn't want to do that in a production environment. So we need to create a scope so the DI container can provide us with the store context. Now this is kind of seeing how the sausage is made. You don't necessarily need to do this often.
But we call ApplicationServices.GetRequiredService and that's an IServiceScopeFactory. CreateScope. Now that we have the service scope, we can say var context = serviceScope.ServiceProvider GetService of type StoreContext.
Now that we have the context, we just need to call initializer.InitializeData passing in the context. This added another using statement for us on line 15, SpyStoreDAL.EF.Initializers. Now you can see the context here is showing up with a squiggle and it doesn't really know if I'm passing in a service provider or a store context.
This is very simple. Let's just make it instead of var, use StoreContext. And that completes configuring the application.
- Creating the .NET Core project
- Adding Entity Framework
- Migrating the data access layer (DAL)
- Configuring services and the HTTP pipeline
- Adding remaining services to the dependency injection container
- Migrating controllers and actions
- Testing the services