Using Dependency Injection7:55 with James Churchill
Let's see how we can update our controller to use constructor injection to declare its dependencies. And let's install a DI container to handle creating object instances and managing the lifetime of those instances.
To follow along committing your changes to this course, you'll need to fork the aspnet-fitness-frog-spa repo. Then you can clone, commit, and push your changes to your fork like this:
git clone <your-fork> cd aspnet-fitness-frog-spa git checkout tags/v3.1 -b using-dependency-injection
DI Container Configuration Overview
After installing the
SimpleInjector.Integration.WebApi.WebHost.QuickStart NuGet package, you'll have a new file in your project's App_Start folder: SimpleInjectorWebApiInitializer.cs. Let's walkthrough the code in that file.
The attribute at the top of the file is using a package called WebActivator to wire up the SimpleInjectorWebApiInitializer
Initialize method to be called right after the
Application_Start method has completed. By using this method, Simple Injector avoided having to modify our project's
Application_Start method in the Global.asax.cs file. For more information about WebActivator, see github.com/davidebbo/WebActivator.
Initialize method instantiates and initializes our DI container. The first line of code instantiates the Simple Injector container.
var container = new Container();
The second line of code sets the default scoped lifestyle for our container.
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
Unfortunately, this code uses a deprecated class for the default scoped lifestyle. While this doesn't generate a compilation error, it'll generate a warning. To eliminate the warning, you can optionally update this line of code to:
container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
There are a number of scoped lifestyle types available. It's important to use the one that best suites your application type. For Web API, you want to use the AsyncScopedLifestyle type. That's what this line of code is doing—it's setting the default scoped lifestyle for our DI container to the AsyncScopedLifestyle type.
InitializeContainer method is called, passing in the DI container.
InitializeContainer method is defined just below the
Initialize method. The
InitializeContainer method is where we'll configure the dependencies for our application.
Then a method on the DI container—
RegisterWebApiControllers—is called, which registers all of our application's API controllers as dependencies.
Verify method is called to verify the configuration of the DI container.
If any configuration errors are found, and exception will be thrown. Then Web API's dependency resolver is set to an instance of the SimpleInjectorWebApiDependencyResolver class.
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
The dependency resolver is responsible for locating dependencies in the DI container. For example, when the DI container is instantiating an instance of the EntriesRepository class, it'll detect that it needs an instance of the Context class to pass to the EntriesRepository's class constructor. The dependency resolver will be used to resolve the Context class dependency to an instance of that class contained within the DI container.
Not only is the dependency resolver used to resolve dependencies between our classes, but it's also used by Web API to resolve controller dependencies. Once Web API has mapped a route to a specific controller, it'll ask the dependency resolver for an instance of that controller class. That's why it was necessary to register our controllers with the DI container.
You need to sign up for Treehouse in order to download course files.Sign up