Leveraging a DI Container7:58 with James Churchill
Now we're ready to install and configure our DI container! We'll also learn about object lifestyles (or lifetimes) and register our application's dependencies with the DI container.
We can use the NuGet package manager to add the necessary package for 0:00 our DI container. 0:04 Right click on the project and I select Manage NugGet Packages. 0:05 If the browse tab isn't selected go ahead and click on it. 0:10 Simple injector provides a variety of quick start packages including one 0:13 for MVC. 0:18 To find it search for simpleinjector.mvc. 0:18 The package that we're looking for 0:25 is the Simpleinjector.MVC3 package it's kind of a confusing name. 0:28 Even though it says MVC3 it's compatible with MVC5 which 0:33 is the version of MVC that we're using go ahead and install the package. 0:37 Installing the NuGat package adds some assembly references to our project, 0:51 Including three assemblies related to SimpleInjector, 0:57 and an assembly named WebActivator. 1:02 The NuGat package also added a code file to our project 1:06 In the App_Start folder named SimpleInjectorInitializer. 1:10 This file contains the code that's being used to configure our DI container. 1:14 This assembly attribute is being used to register our SimpleInjectorInitializer, 1:20 Initialize method, to be called right after our application starts up. 1:26 By using this method, SimpleInjector avoided having to 1:31 modify our project's application start method in the global.asaxcs file. 1:35 See the teacher's notes for more information about web activator. 1:40 The Initialize method is use to instantiate and 1:44 initialize our DI container. 1:47 The first line of code instantiates the DI container. 1:49 And the second line of code sets the DefaultScopedLifestyle 1:52 to an instance of the class WebRequestLifestyle. 1:56 Don't worry too much about what this line of code is doing right now, 1:59 we'll talk more about lifestyles, and what the scope lifestyle is, in just a bit. 2:02 Then, the InitializeContainer method is called, 2:07 passing in an instance of the container. 2:10 The InitializeContainer method is defined down here at the bottom of our class. 2:13 We'll use this method to register our dependencies with the DI container. 2:17 Notice that simple injector is referring to our dependencies as services. 2:22 This is a commonly used term for dependencies as 2:27 they typically provide services for other classes throughout our application. 2:30 I'm gonna go ahead and 2:34 remove this reminder, we'll come back to this method in just a bit. 2:35 After calling the initialized container method, 2:40 a method on the container is called RegisterMvcControllers. 2:43 We pass into that method a reference to our current executing assembly. 2:47 This is the assembly for our ASP.NET MVC application. 2:52 This method is being used to discover all of the controllers in our application and 2:56 then it registers those controllers with a DI container. 3:01 After the controllers are registered, the verify method is called on the container. 3:05 This method, as it sounds like, verifies the configuration of the container 3:09 if any errors are found, an exception will be thrown. 3:14 This last line of code sets the NVC's DependencyResolver to an instance 3:16 of the SimpleInjectorDependencyResolver class, passing in our container. 3:21 The DependencyResolver is responsible for locating dependencies in the DI container. 3:27 For example, when the container is instantiating an instance of 3:32 the Repository class it'll detect that it needs an instance of the context class 3:35 to pass to the repositories class constructor. 3:39 The DependencyResolver will be used to resolve the context class dependency 3:43 to an instance of that class, contained within the DI container. 3:47 Not only is the DependencyResolver used to resolve dependencies between our classes, 3:52 but it's also used by NVC to resolve controller dependencies. 3:57 Once NVC has mapped the route to a specific controller 4:01 it'll ask the DependencyResolver for an instance of that controller class. 4:04 That's why it was necessary to register our controllers with a DI container. 4:09 Now that we've reviewed the boiler plate DI container initialization code in 4:13 the initialized method let',s update the InitializeContainer method. 4:18 We'll use the containers register method to register the types in our application 4:22 that we want the DI container to manage as dependencies. 4:27 When calling the register method we specify the type that want to register 4:30 as the methods to net type parameter, we also need to add the namespace for 4:34 the context class. 4:38 Which is, using Treehouse.SolarSystem.Data. 4:40 And we pass in a lifestyle enumeration value. 4:46 The Lifestyle enumeration value that we pass to the Register method, 4:52 tells the container how many instances of a type should be created. 4:56 And how long each of those instances should live, 5:00 simple injector provides three object lifetime types that we can choose from 5:03 when we register our dependencies. 5:08 With the transient lifetime a new instance is created every time that 5:10 an instance is requested. 5:14 With the scope lifetime for every request within an implicitly or 5:16 explicitly defined scope a single instance will be returned and 5:20 that instance will be disposed when the scope ends. 5:24 And with the Singleton lifetime, only one instance is created per container. 5:28 You can think of Singletons as global object instances. 5:33 In our container configuration, 5:37 we set our default scope lifetime to an instance of the WebRequestLifestyle class. 5:39 By doing this, each WebRequest will be implicitly defined as a scope. 5:44 So registry dependencies with a ScopedLifestyle will mean that an instance 5:48 will be instantiated at the beginning of a request and 5:53 shared across any object servicing that request that are dependent on that type. 5:56 When the request ends, the container will dispose of the instance. 6:02 Let's finish registering our dependencies. 6:06 It's typical to have a single database context and repository instance for 6:11 each request. 6:16 So let's add a data dependencies as Scope dependencies. 6:18 So we added the context class but now let's add the repository class. 6:22 And that's it these are our applications to dependencies. 6:31 So now let's test our DI container. 6:34 Before we run the application, 6:37 let's set a break point in our controller's constructor 6:38 Then let's run the application and, we hit our break point. 6:51 This is the first of two times that we hit our break point. 6:55 This first time is when the configuration of our container is being verified. 6:58 If we continue execution we'll hit our break point a second time. 7:03 If we hover over the repository parameter we can see 7:08 that it has a reference to a repository object. 7:11 And if we expand the repository object, 7:15 we can see that its context private field has a reference to a context object. 7:17 And if we continue execution, here's out list of planets. 7:24 Congrats, you've just configured DI for our NVC application. 7:29 As our application grows, we can continue to add new dependencies to our DI 7:34 containers configuration and declare dependencies via our class constructors. 7:38 It's a clean, efficient way to manage our app's dependencies. 7:43 Adding a DI container to an ASP.NET MVC application isn't difficult to do. 7:46 But ASP.NET Core makes it even simpler, let's see how next. 7:52
You need to sign up for Treehouse in order to download course files.Sign up