You’ve seen where the dependency will be injected, but you haven’t seen how it actually happens. You might think that we do it like before:
new IndexModel(new Logger());
We won’t need to type this because it is all handled by ASP.NET’s IoC container. In a basic ASP.NET application, you’re not really going to see that code at all.
Instead of the above code, all we have to do is register the services that will act as dependencies, so that the container knows what to inject when a page model asks for them.
We do this in ConfigureServices()
:
ConfigureServices(IServiceProvider services) { services.AddScoped<ISomething, Something>(); }
In the above code we are saying: “Hey IoC container, whenever a class asks for an ISomething
service, inject a Something
instance into it”. We’ll explain AddScoped()
in a few exercises.
Then we can request that service in our page models:
private readonly ISomething _something; public IndexModel(ISomething something) { _something = something; }
This approach to dependency injection makes the Dependency Inversion and Inversion of Control principles more obvious:
- Modules should depend on abstractions: the page model only references an interface, i.e. an abstraction.
- Don’t call us, we’ll call you: we never see the service object instantiated or passed into a constructor. All of that is handled by the framework.
Instructions
We’ve provided a service for you called IDataStore
with an implementation called SongDataStore
. Register it in Startup.cs using this template…
services.AddScoped<TService,TImplementation>()
…where TService
will be your service and TImplementation
is your implementation.
Add the IDataStore
service in IndexModel.cshtml.cs:
- Declare a
private
readonly
field of typeIDataStore
. - Add an
IDataStore
parameter to the constructor. - In the constructor body, store the parameter’s value in your new field.
Use the IDataStore
service in the page model:
- In
OnGet()
, call the declaredIDataStore
field’sGetAll()
method and store the returned value inItems
.