What is Dependency Injection?7:20 with James Churchill
In this video, we'll learn about dependencies and how dependency injection can help to improve the manageability and testability of our code.
Using DI with Web API
If you'd to learn how to use DI with the ASP.NET Web API framework, check out this course on Web API:
If you'd like to follow along with this workshop, you can download the starting project files using this link:
[MUSIC] 0:00 Hi, my name is James. 0:04 In this workshop, you'll learn about dependency injection and 0:06 how to use it in an ASP.NET MVC application. 0:11 We'll start with an overview of what dependencies are, and 0:15 how dependency injection, or DI, 0:17 can help you to improve the manageability and testability of your code. 0:20 We'll also see how to select, install, and 0:25 configure one of the popular DI containers available for ASP.NET MVC. 0:28 And we'll finish up with a look at DI in the ASP.NET Core web framework. 0:33 We won't be covering in this workshop how to use 0:39 DI with the ASP.NET Web API framework. 0:42 That'll be covered in a future course on Web API, see the teacher's notes for 0:45 more information. 0:49 Here's the project that we'll be using in this workshop, 0:51 open in the community edition of Visual Studio 2017. 0:54 Our project name is Treehouse.SolarSystem. 0:56 If you'd like to follow along, see the teacher's notes for 1:01 a link to download the project files. 1:03 Our application is a very basic ASP.NET MVC application. 1:05 We have a single controller named PlanetsController, 1:10 and we have a single model named Planet. 1:15 We also have some entity framework related classes in the Data folder. 1:19 We have a Context class, a Database Initializer class, 1:24 that seeds our database with some data, and a single Repository class. 1:29 Let's see what our application does. 1:34 And as you might expect, it displays a list of the planets in our solar system, 1:37 all nine, I mean eight of them, sorry Pluto. 1:41 Let's review how our application displays the list of planets that you just saw. 1:45 Here's the index action method that displays the list of planets. 1:49 We can see here that it's calling a method called GetPlanets 1:53 on a repository private field. 1:57 The repository private field is of type Repository, which 1:59 you can see in our class constructor, we're instantiating an instance. 2:04 We're also instantiating an instance of the Context class, and 2:08 passing that into the repository's constructor. 2:11 The Repository class, GetPlanets method, is using the Context class to query 2:17 the underlying database for the list of planets. 2:22 Back in the controller, we can see that we're also overriding the Dispose method, 2:26 which is being used to dispose the _context 2:31 when our controller is being disposed. 2:34 We're doing this in order to control the lifetime of our _context object. 2:36 So, what are dependencies? 2:41 As we just saw, our controller class, well specifically the index action method, 2:43 is dependent upon an instance of the repository class. 2:48 And, the repository class is dependent upon an instance of the context class. 2:52 This chain of dependencies is sometimes called a dependency tree or 2:59 a dependency graph. 3:03 The context and repository classes are examples of database or data dependencies. 3:05 There are many other types of dependencies that your application might have. 3:10 External dependencies, like storage, messaging services, 3:15 like email or texting, or any other restful service, or HTTP API. 3:19 Or maybe internal dependencies like app settings, user authentication, 3:24 session management or really any business logic that's specific to your application, 3:29 for instance, maybe a shopping card for an e-commerce application. 3:35 Our controller shouldn't really be concerned with instantiating instances 3:40 of its dependencies, or controlling the lifetime of those dependencies. 3:44 Ideally, we should just be able to ask for our dependencies. 3:49 One way to do that would be to declare our dependencies 3:53 through constructor parameters. 3:56 Let's take a look at what that would look like. 3:58 Let's add a parameter of type Repository named repository. 4:01 Then, we can replace this instantiation of the repository class with a reference to 4:08 that parameter. 4:13 We can also get rid of this instantiation of the context class. 4:16 And, this boolean disposed private field and the context private field. 4:21 Even more, we can get rid of this dispose override. 4:28 That's a lot less code, isn't it? 4:36 With this approach, the underlying app framework would provide our controller 4:39 with an instance of the repository class. 4:43 And for our repository class, it would supply an instance of the context class. 4:48 And, it would also manage the live time of the context for us. 4:54 This technique is known as constructor injection. 4:58 Constructor injection is part of a broader design pattern 5:01 known as dependency injection. 5:04 Dependency injection, or 5:07 DI, is related to the inversion of control, or IOC design principle. 5:08 As we just saw in our example, using DI classes, like our controller, 5:14 no longer need to concern themselves with how their dependencies are instantiated. 5:19 In fact, any of our controller's dependencies, like the repository class, 5:23 in turn might have their own dependencies. 5:27 That's no problem. 5:30 It's still not the concern of our controller. 5:31 Directly instantiating dependencies within a class, 5:34 tightly couples that class to its dependencies. 5:37 Using DI helps us to create loosely coupled classes or components. 5:40 Loose coupling improves code reusability, 5:44 making it easier to reuse our classes in new ways or in new environments. 5:47 DI also helps to improve the testability of our code. 5:53 For example, if we wanted to unit test our controller's index action method, 5:56 we could provide the controller with an instance of the repository class 6:01 that would avoid querying the underlying database. 6:04 Instead, it'd simply return a static collection of planets. 6:07 Supplying this mock repository class to the controller class 6:11 would allow our unit test to run in a performant predictable way. 6:16 Constructor injection isn't the only way to implement DI. 6:20 Property injection and 6:23 method injection are two alternative approaches that you can use. 6:25 We won't be covering these approaches in this workshop, 6:28 as we'll be using constructor injection. 6:31 For more information about the IOC design principle, property injection, 6:34 method injection, and an example of DI and unit testing, see the teacher's notes. 6:38 Dependency injection is a popular design pattern. 6:44 DI can be used with virtually any language or platform, with or 6:47 without the support of an external library. 6:50 Google's Angular framework and Microsoft's ASP.NET Core web framework, 6:54 as we'll see later in this workshop, provide built-in support for DI. 6:58 Unfortunately, the ASP.NET MVC web framework doesn't provide support for 7:02 DI out of the box. 7:08 You need to install and configure what's known as a DI container. 7:09 In the next video, we'll learn about DI containers and 7:13 select a DI container library to use in our project. 7:16
You need to sign up for Treehouse in order to download course files.Sign up