ASP.NET MVC 4 Dependency Injection
[!NOTE] This Hands-on Lab assumes you have basic knowledge of ASP.NET MVC and ASP.NET MVC 4 filters. If you have not used ASP.NET MVC 4 filters before, we recommend you to go over ASP.NET MVC Custom Action Filters Hands-on Lab.
All sample code and snippets are included in the Web Camps Training Kit, available at https://www.microsoft.com/en-us/download/29843.
In Object Oriented Programming paradigm, objects work together in a collaboration model where there are contributors and consumers. Naturally, this communication model generates dependencies between objects and components, becoming difficult to manage when complexity increases.
Class dependencies and model complexity
You have probably heard about the Factory Pattern and the separation between the interface and the implementation using services, where the client objects are often responsible for service location.
The Dependency Injection pattern is a particular implementation of Inversion of Control. Inversion of Control (IoC) means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source (for example, an xml configuration file).
Dependency Injection (DI) means that this is done without the object intervention, usually by a framework component that passes constructor parameters and set properties.
### The Dependency Injection (DI) Design Pattern
At a high level, the goal of Dependency Injection is that a client class (e.g. the golfer) needs something that satisfies an interface (e.g. IClub). It doesn’t care what the concrete type is (e.g. WoodClub, IronClub, WedgeClub or PutterClub), it wants someone else to handle that (e.g. a good caddy). The Dependency Resolver in ASP.NET MVC can allow you to register your dependency logic somewhere else (e.g. a container or a bag of clubs).
Dependency Injection - Golf analogy
The advantages of using Dependency Injection pattern and Inversion of Control are the following:
- Reduces class coupling
- Increases code reusing
- Improves code maintainability
- Improves application testing
[!NOTE] Dependency Injection is sometimes compared with Abstract Factory Design Pattern, but there is a slight difference between both approaches. DI has a Framework working behind to solve dependencies by calling the factories and the registered services.
Now that you understand the Dependency Injection Pattern, you will learn throughout this lab how to apply it in ASP.NET MVC 4. You will start using Dependency Injection in the Controllers to include a database access service. Next, you will apply Dependency Injection to the Views to consume a service and show information. Finally, you will extend the DI to ASP.NET MVC 4 Filters, injecting a custom action filter in the solution.
In this Hands-on Lab, you will learn how to:
- Integrate ASP.NET MVC 4 with Unity for Dependency Injection using NuGet Packages
- Use Dependency Injection inside an ASP.NET MVC Controller
- Use Dependency Injection inside an ASP.NET MVC View
- Use Dependency Injection inside an ASP.NET MVC Action Filter
[!NOTE] This Lab is using Unity.Mvc3 NuGet Package for dependency resolution, but it is possible to adapt any Dependency Injection Framework to work with ASP.NET MVC 4.
You must have the following items to complete this lab:
- Microsoft Visual Studio Express 2012 for Web or superior (read Appendix A for instructions on how to install it).
Installing Code Snippets
For convenience, much of the code you will be managing along this lab is available as Visual Studio code snippets. To install the code snippets run ..vsi file.
If you are not familiar with the Visual Studio Code Snippets, and want to learn how to use them, you can refer to the appendix from this document “Appendix B: Using Code Snippets”.
This Hands-On Lab is comprised by the following exercises:
[!NOTE] Each exercise is accompanied by an End folder containing the resulting solution you should obtain after completing the exercises. You can use this solution as a guide if you need additional help working through the exercises.
Estimated time to complete this lab: 30 minutes.
### Exercise 1: Injecting a Controller
In this exercise, you will learn how to use Dependency Injection in ASP.NET MVC Controllers by integrating Unity using a NuGet Package. For that reason, you will include services into your MvcMusicStore controllers to separate the logic from the data access. The services will create a new dependency in the controller constructor, which will be resolved using Dependency Injection with the help of Unity.
This approach will show you how to generate less coupled applications, which are more flexible and easier to maintain and test. You will also learn how to integrate ASP.NET MVC with Unity.
#### About StoreManager Service
The MVC Music Store provided in the begin solution now includes a service that manages the Store Controller data named StoreService. Below you will find the Store Service implementation. Note that all the methods return Model entities.
[!code-csharpMain]
1: namespace MvcMusicStore.Controllers
2: {
3: using System.Web.Mvc;
4: using MvcMusicStore.Filters;
5: using MvcMusicStore.Services;
6:
7: [MyNewCustomActionFilter(Order = 1)]
8: [CustomActionFilter(Order = 2)]
9: public class StoreController : Controller
10: {
11: private IStoreService service;
12:
13: public StoreController(IStoreService service)
14: {
15: this.service = service;
16: }
17:
18: // GET: /Store/
19: public ActionResult Details(int id)
20: {
21: var album = this.service.GetAlbum(id);
22: if (album == null)
23: {
24: return this.HttpNotFound();
25: }
26:
27: return this.View(album);
28: }
29:
30: public ActionResult Browse(string genre)
31: {
32: // Retrieve Genre and its Associated Albums from database
33: var genreModel = this.service.GetGenreByName(genre);
34:
35: return this.View(genreModel);
36: }
37:
38: public ActionResult Index()
39: {
40: var genres = this.service.GetGenres();
41:
42: return this.View(genres);
43: }
44:
45: // GET: /Store/GenreMenu
46: public ActionResult GenreMenu()
47: {
48: var genres = this.service.GetGenres();
49:
50: return this.PartialView(genres);
51: }
52: }
53: }
StoreController from the begin solution now consumes StoreService. All the data references were removed from StoreController, and now possible to modify the current data access provider without changing any method that consumes StoreService.
You will find below that the StoreController implementation has a dependency with StoreService inside the class constructor.
[!NOTE] The dependency introduced in this exercise is related to Inversion of Control (IoC).
The StoreController class constructor receives an IStoreService type parameter, which is essential to perform service calls from inside the class. However, StoreController does not implement the default constructor (with no parameters) that any controller must have to work with ASP.NET MVC.
To resolve the dependency, the controller has to be created by an abstract factory (a class that returns any object of the specified type).
[!code-csharpMain]
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.Mvc;
6: using MvcMusicStore.ViewModels;
7: using MvcMusicStore.Models;
8: using MvcMusicStore.Services;
9:
10: namespace MvcMusicStore.Controllers
11: {
12: public class StoreController : Controller
13: {
14: private IStoreService service;
15:
16: public StoreController(IStoreService service)
17: {
18: this.service = service;
19: }
20:
21: //
22: // GET: /Store/
23: public ActionResult Index()
24: {
25: // Create list of genres
26: var genres = this.service.GetGenreNames();
27:
28: // Create your view model
29: var viewModel = new StoreIndexViewModel
30: {
31: Genres = genres.ToList(),
32: NumberOfGenres = genres.Count()
33: };
34:
35: return View(viewModel);
36: }
37:
38: //
39: // GET: /Store/Browse?genre=Disco
40: public ActionResult Browse(string genre)
41: {
42: var genreModel = this.service.GetGenreByName(genre);
43:
44: var viewModel = new StoreBrowseViewModel()
45: {
46: Genre = genreModel,
47: Albums = genreModel.Albums.ToList()
48: };
49:
50: return View(viewModel);
51: }
52:
53: //
54: // GET: /Store/Details/5
55: public ActionResult Details(int id)
56: {
57: var album = this.service.GetAlbum(id);
58:
59: return View(album);
60: }
61: }
62: }
[!NOTE] You will get an error when the class tries to create the StoreController without sending the service object, as there is no parameterless constructor declared.
#### Task 1 - Running the Application
In this task, you will run the Begin application, which includes the service into the Store Controller that separates the data access from the application logic.
When running the application, you will receive an exception, as the controller service is not passed as a parameter by default:
Open the Begin solution located in **Source01-Injecting Controller*.
- You will need to download some missing NuGet packages before continue. To do this, click the Project menu and select Manage NuGet Packages.
- In the Manage NuGet Packages dialog, click Restore in order to download missing packages.
- Finally, build the solution by clicking Build | Build Solution.
[!NOTE] One of the advantages of using NuGet is that you don’t have to ship all the libraries in your project, reducing the project size. With NuGet Power Tools, by specifying the package versions in the Packages.config file, you will be able to download all the required libraries the first time you run the project. This is why you will have to run these steps after you open an existing solution from this lab.
Press Ctrl + F5 to run the application without debugging. You will get the error message “No parameterless constructor defined for this object”:
Error while running ASP.NET MVC Begin ApplicationClose the browser.
In the following steps you will work on the Music Store Solution to inject the dependency this controller needs.
#### Task 2 - Including Unity into MvcMusicStore Solution
In this task, you will include Unity.Mvc3 NuGet Package to the solution.
[!NOTE] Unity.Mvc3 package was designed for ASP.NET MVC 3, but it is fully compatible with ASP.NET MVC 4.
Unity is a lightweight, extensible dependency injection container with optional support for instance and type interception. It is a general-purpose container for use in any type of .NET application. It provides all the common features found in dependency injection mechanisms including: object creation, abstraction of requirements by specifying dependencies at runtime and flexibility, by deferring the component configuration to the container.
- Install Unity.Mvc3 NuGet Package in the MvcMusicStore project. To do this, open the Package Manager Console from View | Other Windows.
Run the following command.
PMC
[!code-powershellMain]
1: Install-Package Unity.Mvc3
Once the Unity.Mvc3 package is installed, explore the files and folders it automatically adds in order to simplify Unity configuration.
Unity.Mvc3 package installed
#### Task 3 - Registering Unity in Global.asax.cs Application_Start
In this task, you will update the Application_Start method located in Global.asax.cs to call the Unity Bootstrapper initializer and then, update the Bootstrapper file registering the Service and Controller you will use for Dependency Injection.
Now, you will hook up the Bootstrapper which is the file that initializes the Unity container and Dependency Resolver. To do this, open Global.asax.cs and add the following highlighted code within the Application_Start method.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex01 - Initialize Unity)
[!code-csharpMain]1: protected void Application_Start()
2: {
3: AreaRegistration.RegisterAllAreas();
4:
5: WebApiConfig.Register(GlobalConfiguration.Configuration);
6: FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
7: RouteConfig.RegisterRoutes(RouteTable.Routes);
8: BundleConfig.RegisterBundles(BundleTable.Bundles);
9:
10: Bootstrapper.Initialise();
11:
12: AppConfig.Configure();
13: }
- Open Bootstrapper.cs file.
Include the following namespaces: MvcMusicStore.Services and MusicStore.Controllers.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex01 - Bootstrapper Adding Namespaces)
[!code-csharpMain]1: using System.Web.Mvc;
2: using Microsoft.Practices.Unity;
3: using Unity.Mvc3;
4: using MvcMusicStore.Services;
5: using MvcMusicStore.Controllers;
Replace BuildUnityContainer method’s content with the following code that registers Store Controller and Store Service.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex01 - Register Store Controller and Service)
[!code-csharpMain]
1: private static IUnityContainer BuildUnityContainer()
2: {
3: var container = new UnityContainer();
4:
5: container.RegisterType<IStoreService, StoreService>();
6: container.RegisterType<IController, StoreController>("Store");
7:
8: return container;
9: }
#### Task 4 - Running the Application
In this task, you will run the application to verify that it can now be loaded after including Unity.
Press F5 to run the application, the application should now load without showing any error message.
Running Application with Dependency InjectionBrowse to /Store. This will invoke StoreController, which is now created using Unity.
MVC Music StoreClose the browser.
In the following exercises you will learn how to extend the Dependency Injection scope to use it inside ASP.NET MVC Views and Action Filters.
### Exercise 2: Injecting a View
In this exercise, you will learn how to use Dependency Injection in a view with the new features of ASP.NET MVC 4 for Unity integration. In order to do that, you will call a custom service inside the Store Browse View, which will show a message and an image below.
Then, you will integrate the project with Unity and create a custom dependency resolver to inject the dependencies.
#### Task 1 - Creating a View that Consumes a Service
In this task, you will create a view that performs a service call to generate a new dependency. The service consists in a simple messaging service included in this solution.
Open the Begin solution located in the Source02-Injecting View* folder. Otherwise, you might continue using the End** solution obtained by completing the previous exercise.
- If you opened the provided Begin solution, you will need to download some missing NuGet packages before continue. To do this, click the Project menu and select Manage NuGet Packages.
- In the Manage NuGet Packages dialog, click Restore in order to download missing packages.
- Finally, build the solution by clicking Build | Build Solution.
[!NOTE] One of the advantages of using NuGet is that you don’t have to ship all the libraries in your project, reducing the project size. With NuGet Power Tools, by specifying the package versions in the Packages.config file, you will be able to download all the required libraries the first time you run the project. This is why you will have to run these steps after you open an existing solution from this lab.
For more information, see this article: http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.
Include the MessageService.cs and the IMessageService.cs classes located in the Source * folder in /Services. To do this, right-click Services** folder and select Add Existing Item. Browse to the files’ location and include them.
Adding Message Service and Service Interface
[!NOTE] The IMessageService interface defines two properties implemented by the MessageService class. These properties -Message and ImageUrl- store the message and the URL of the image to be displayed.
Create the folder /Pages in the project’s root folder, and then add the existing class MyBasePage.cs from **Source*. The base page you will inherit from has the following structure.
[!code-csharpMain]1: namespace MvcMusicStore.Pages
2: {
3: using System;
4: using System.Collections.Generic;
5: using System.Linq;
6: using System.Web;
7: using Microsoft.Practices.Unity;
8: using MvcMusicStore.Models;
9: using MvcMusicStore.Services;
10:
11: public class MyBasePage : System.Web.Mvc.WebViewPage<Genre>
12: {
13: [Dependency]
14: public IMessageService MessageService { get; set; }
15:
16: public override void
17:
18: Execute()
19: {
20: }
21: }
22: }
Open Browse.cshtml view from /Views/Store folder, and make it inherit from MyBasePage.cs.
[!code-cshtmlMain]1: @inherits MvcMusicStore.Pages.MyBasePage
2: @{
3: ViewBag.Title = "Browse Albums";
4: }
In the Browse view, add a call to MessageService to display an image and a message retrieved by the service. (C#)
[!code-cshtmlMain]
1: @inherits MvcMusicStore.Pages.MyBasePage
2: @{
3: Viewbag.Title = "Browse Albums";
4: }
5: <div>
6: @this.MessageService.Message
7: <br />
8: <img alt="@this.MessageService.Message" src="@this.MessageService.ImageUrl" />
9: </div>
10: ...
#### Task 2 - Including a Custom Dependency Resolver and a Custom View Page Activator
In the previous task, you injected a new dependency inside a view to perform a service call inside it. Now, you will resolve that dependency by implementing the ASP.NET MVC Dependency Injection interfaces IViewPageActivator and IDependencyResolver. You will include in the solution an implementation of IDependencyResolver that will deal with the service retrieval by using Unity. Then, you will include another custom implementation of IViewPageActivator interface that will solve the creation of the views.
[!NOTE] Since ASP.NET MVC 3, the implementation for Dependency Injection had simplified the interfaces to register services. IDependencyResolver and IViewPageActivator are part of ASP.NET MVC 3 features for Dependency Injection.
- IDependencyResolver interface replaces the previous IMvcServiceLocator. Implementers of IDependencyResolver must return an instance of the service or a service collection.
[!code-csharpMain]
1: public interface IDependencyResolver {2: object GetService(Type serviceType);3: IEnumerable<object> GetServices(Type serviceType);4: }
- IViewPageActivator interface provides more fine-grained control over how view pages are instantiated via dependency injection. The classes that implement IViewPageActivator interface can create view instances using context information.
[!code-csharpMain]
1: public interface IViewPageActivator {2: object Create(ControllerContext controllerContext, Type type);3: }
- Create the /Factories folder in the project’s root folder.
Include CustomViewPageActivator.cs to your solution from /Sources/Assets/ to Factories folder. To do that, right-click the /Factories folder, select Add | Existing Item and then select CustomViewPageActivator.cs. This class implements the IViewPageActivator interface to hold the Unity Container.
[!code-csharpMain]
1: namespace MvcMusicStore.Factories
2: {
3: using System;
4: using System.Collections.Generic;
5: using System.Linq;
6: using System.Web;
7: using System.Web.Mvc;
8: using Microsoft.Practices.Unity;
9:
10: public class CustomViewPageActivator : IViewPageActivator
11: {
12: private IUnityContainer container;
13:
14: public CustomViewPageActivator(IUnityContainer container)
15: {
16: this.container = container;
17: }
18:
19: public object Create(ControllerContext controllerContext, Type type)
20: {
21: return this.container.Resolve(type);
22: }
23: }
24: }
[!NOTE] CustomViewPageActivator is responsible for managing the creation of a view by using a Unity container.
Include UnityDependencyResolver.cs file from /Sources/Assets to /Factories folder. To do that, right-click the /Factories folder, select Add | Existing Item and then select UnityDependencyResolver.cs file.
[!code-csharpMain]
1: namespace MvcMusicStore.Factories
2: {
3: using System;
4: using System.Collections.Generic;
5: using System.Linq;
6: using System.Web;
7: using System.Web.Mvc;
8: using Microsoft.Practices.Unity;
9:
10: public class UnityDependencyResolver : IDependencyResolver
11: {
12: private IUnityContainer container;
13:
14: private IDependencyResolver resolver;
15:
16: public UnityDependencyResolver(IUnityContainer container, IDependencyResolver resolver)
17: {
18: this.container = container;
19: this.resolver = resolver;
20: }
21:
22: public object GetService(Type serviceType)
23: {
24: try
25: {
26: return this.container.Resolve(serviceType);
27: }
28: catch
29: {
30: return this.resolver.GetService(serviceType);
31: }
32: }
33:
34: public IEnumerable<object> GetServices(Type serviceType)
35: {
36: try
37: {
38: return this.container.ResolveAll(serviceType);
39: }
40: catch
41: {
42: return this.resolver.GetServices(serviceType);
43: }
44: }
45: }
46: }
[!NOTE] UnityDependencyResolver class is a custom DependencyResolver for Unity. When a service cannot be found inside the Unity container, the base resolver is invocated.
In the following task both implementations will be registered to let the model know the location of the services and the views.
#### Task 3 - Registering for Dependency Injection within Unity container
In this task, you will put all the previous things together to make Dependency Injection work.
Up to now your solution has the following elements:
- A Browse View that inherits from MyBaseClass and consumes MessageService.
- An intermediate class -MyBaseClass- that has dependency injection declared for the service interface.
- A service - MessageService - and its interface IMessageService.
- A custom dependency resolver for Unity - UnityDependencyResolver - that deals with service retrieval.
- A View Page activator - CustomViewPageActivator - that creates the page.
To inject Browse View, you will now register the custom dependency resolver in the Unity container.
- Open Bootstrapper.cs file.
Register an instance of MessageService into the Unity container to initialize the service:
(Code Snippet - ASP.NET Dependency Injection Lab - Ex02 - Register Message Service)
[!code-csharpMain]1: private static IUnityContainer BuildUnityContainer()
2: {
3: var container = new UnityContainer();
4:
5: container.RegisterType<IStoreService, StoreService>();
6: container.RegisterType<IController, StoreController>("Store");
7:
8: container.RegisterInstance<IMessageService>(new MessageService
9: {
10: Message = "You are welcome to our Web Camps Training Kit!",
11: ImageUrl = "/Content/Images/webcamps.png"
12: });
13: //...
14: }
Add a reference to MvcMusicStore.Factories namespace.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex02 - Factories Namespace)
[!code-csharpMain]1: using System.Web.Mvc;
2: using Microsoft.Practices.Unity;
3: using Unity.Mvc3;
4: using MvcMusicStore.Services;
5: using MvcMusicStore.Controllers;
6: using MvcMusicStore.Factories;
Register CustomViewPageActivator as a View Page activator into the Unity container:
(Code Snippet - ASP.NET Dependency Injection Lab - Ex02 - Register CustomViewPageActivator)
[!code-csharpMain]1: private static IUnityContainer BuildUnityContainer()
2: {
3: var container = new UnityContainer();
4:
5: container.RegisterType<IStoreService, StoreService>();
6: container.RegisterType<IController, StoreController>("Store");
7:
8: container.RegisterInstance<IMessageService>(new MessageService
9: {
10: Message = "You are welcome to our Web Camps Training Kit!",
11: ImageUrl = "/Content/Images/webcamps.png"
12: });
13:
14: container.RegisterType<IViewPageActivator, CustomViewPageActivator>(new InjectionConstructor(container));
15:
16: return container;
17: }
Replace ASP.NET MVC 4 default dependency resolver with an instance of UnityDependencyResolver. To do this, replace Initialise method content with the following code:
(Code Snippet - ASP.NET Dependency Injection Lab - Ex02 - Update Dependency Resolver)
[!code-csharpMain]
1: public static void Initialise()
2: {
3: var container = BuildUnityContainer();
4:
5: DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));
6:
7: IDependencyResolver resolver = DependencyResolver.Current;
8:
9: IDependencyResolver newResolver = new Factories.UnityDependencyResolver(container, resolver);
10:
11: DependencyResolver.SetResolver(newResolver);
12: }
[!NOTE] ASP.NET MVC provides a default dependency resolver class. To work with custom dependency resolvers as the one we have created for unity, this resolver has to be replaced.
#### Task 4 - Running the Application
In this task, you will run the application to verify that the Store Browser consumes the service and shows the image and the message retrieved:
- Press F5 to run the application.
Click Rock within the Genres Menu and see how the MessageService was injected to the view and loaded the welcome message and the image. In this example, we are entering to “Rock”:
MVC Music Store - View InjectionClose the browser.
### Exercise 3: Injecting Action Filters
In the previous Hands-On lab Custom Action Filters you have worked with filters customization and injection. In this exercise, you will learn how to inject filters with Dependency Injection by using the Unity container. To do that, you will add to the Music Store solution a custom action filter that will trace the activity of the site.
#### Task 1 - Including the Tracking Filter in the Solution
In this task, you will include in the Music Store a custom action filter to trace events. As custom action filter concepts are already treated in the previous Lab “Custom Action Filters”, you will just include the filter class from the Assets folder of this lab, and then create a Filter Provider for Unity:
Open the Begin solution located in the Source03 - Injecting Action Filter* folder. Otherwise, you might continue using the End** solution obtained by completing the previous exercise.
- If you opened the provided Begin solution, you will need to download some missing NuGet packages before continue. To do this, click the Project menu and select Manage NuGet Packages.
- In the Manage NuGet Packages dialog, click Restore in order to download missing packages.
- Finally, build the solution by clicking Build | Build Solution.
[!NOTE] One of the advantages of using NuGet is that you don’t have to ship all the libraries in your project, reducing the project size. With NuGet Power Tools, by specifying the package versions in the Packages.config file, you will be able to download all the required libraries the first time you run the project. This is why you will have to run these steps after you open an existing solution from this lab.
For more information, see this article: http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.
Include TraceActionFilter.cs file from /Sources/Assets to /Filters folder.
[!code-csharpMain]
1: namespace MvcMusicStore.Filters
2: {
3: using System;
4: using System.Collections.Generic;
5: using System.Linq;
6: using System.Web;
7: using System.Web.Mvc;
8:
9: public class TraceActionFilter : IActionFilter
10: {
11: public void OnActionExecuted(ActionExecutedContext filterContext)
12: {
13: filterContext.HttpContext.Trace.Write("OnActionExecuted");
14: filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
15: filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
16: }
17:
18: public void OnActionExecuting(ActionExecutingContext filterContext)
19: {
20: filterContext.HttpContext.Trace.Write("OnActionExecuting");
21: filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName);
22: filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
23: }
24: }
25: }
[!NOTE] This custom action filter performs ASP.NET tracing. You can check “ASP.NET MVC 4 local and Dynamic Action Filters” Lab for more reference.
- Add the empty class FilterProvider.cs to the project in the folder /Filters.
Add the System.Web.Mvc and Microsoft.Practices.Unity namespaces in FilterProvider.cs.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex03 - Filter Provider Adding Namespaces)
[!code-csharpMain]1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Web;
5: using System.Web.Mvc;
6: using Microsoft.Practices.Unity;
7:
8: namespace MvcMusicStore.Filters
9: {
10: public class FilterProvider
11: {
12: }
13: }
Make the class inherit from IFilterProvider Interface.
[!code-csharpMain]1: namespace MvcMusicStore.Filters
2: {
3: public class FilterProvider : IFilterProvider
4: {
5: }
6: }
Add a IUnityContainer property in the FilterProvider class, and then create a class constructor to assign the container.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex03 - Filter Provider Constructor)
[!code-csharpMain]
1: public class FilterProvider : IFilterProvider
2: {
3: private IUnityContainer container;
4:
5: public FilterProvider(IUnityContainer container)
6: {
7: this.container = container;
8: }
9: }
[!NOTE] The filter provider class constructor is not creating a new object inside. The container is passed as a parameter, and the dependency is solved by Unity.
In the FilterProvider class, implement the method GetFilters from IFilterProvider interface.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex03 - Filter Provider GetFilters)
[!code-csharpMain]
1: public class FilterProvider : IFilterProvider
2: {
3: private IUnityContainer container;
4:
5: public FilterProvider(IUnityContainer container)
6: {
7: this.container = container;
8: }
9:
10: public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
11: {
12: foreach (IActionFilter actionFilter in this.container.ResolveAll<IActionFilter>())
13: {
14: yield return new Filter(actionFilter, FilterScope.First, null);
15: }
16: }
17: }
#### Task 2 - Registering and Enabling the Filter
In this task, you will enable site tracking. To do that, you will register the filter in Bootstrapper.cs BuildUnityContainer method to start tracing:
Open Web.config located in the project root and enable trace tracking at System.Web group.
[!code-xmlMain]1: <system.web>
2: <trace enabled="true"/>
3: <compilation debug="true" targetFramework="4.5">
- Open Bootstrapper.cs at project root.
Add a reference to the MvcMusicStore.Filters namespace.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex03 - Bootstrapper Adding Namespaces)
[!code-csharpMain]1: using System.Web.Mvc;
2: using Microsoft.Practices.Unity;
3: using Unity.Mvc3;
4: using MvcMusicStore.Services;
5: using MvcMusicStore.Controllers;
6: using MvcMusicStore.Factories;
7: using MvcMusicStore.Filters;
Select the BuildUnityContainer method and register the filter in the Unity Container. You will have to register the filter provider as well as the action filter.
(Code Snippet - ASP.NET Dependency Injection Lab - Ex03 - Register FilterProvider and ActionFilter)
[!code-csharpMain]
1: private static IUnityContainer BuildUnityContainer()
2: {
3: var container = new UnityContainer();
4:
5: //...
6:
7: container.RegisterInstance<IFilterProvider>("FilterProvider", new FilterProvider(container));
8: container.RegisterInstance<IActionFilter>("LogActionFilter", new TraceActionFilter());
9:
10: return container;
11: }
#### Task 3 - Running the Application
In this task, you will run the application and test that the custom action filter is tracing the activity:
- Press F5 to run the application.
Click Rock within the Genres Menu. You can browse to more genres if you want to.
Music StoreBrowse to /Trace.axd to see the Application Trace page, and then click View Details.
Application Trace Log
Application Trace - Request DetailsClose the browser.
By completing this Hands-On Lab you have learned how to use Dependency Injection in ASP.NET MVC 4 by integrating Unity using a NuGet Package. To achieve that, you have used Dependency Injection inside controllers, views and action filters.
The following concepts were covered:
- ASP.NET MVC 4 Dependency Injection features
- Unity integration using Unity.Mvc3 NuGet Package
- Dependency Injection in Controllers
- Dependency Injection in Views
- Dependency injection of Action Filters
## Appendix A: Installing Visual Studio Express 2012 for Web
You can install Microsoft Visual Studio Express 2012 for Web or another “Express” version using the Microsoft Web Platform Installer. The following instructions guide you through the steps required to install Visual studio Express 2012 for Web using Microsoft Web Platform Installer.
- Go to [https://go.microsoft.com/? linkid=9810169](https://go.microsoft.com/?linkid=9810169). Alternatively, if you already have installed Web Platform Installer, you can open it and search for the product “Visual Studio Express 2012 for Web with Windows Azure SDK”.
- Click on Install Now. If you do not have Web Platform Installer you will be redirected to download and install it first.
Once Web Platform Installer is open, click Install to start the setup.
Install Visual Studio ExpressRead all the products’ licenses and terms and click I Accept to continue.
Accepting the license termsWait until the downloading and installation process completes.
Installation progressWhen the installation completes, click Finish.
Installation completed- Click Exit to close Web Platform Installer.
To open Visual Studio Express for Web, go to the Start screen and start writing “VS Express”, then click on the VS Express for Web tile.
VS Express for Web tile
## Appendix B: Using Code Snippets
With code snippets, you have all the code you need at your fingertips. The lab document will tell you exactly when you can use them, as shown in the following figure.
Using Visual Studio code snippets to insert code into your project
To add a code snippet using the keyboard (C# only)
- Place the cursor where you would like to insert the code.
- Start typing the snippet name (without spaces or hyphens).
- Watch as IntelliSense displays matching snippets’ names.
- Select the correct snippet (or keep typing until the entire snippet’s name is selected).
- Press the Tab key twice to insert the snippet at the cursor location.
Start typing the snippet name
Press Tab to select the highlighted snippet
Press Tab again and the snippet will expand
To add a code snippet using the mouse (C#, Visual Basic and XML) 1. Right-click where you want to insert the code snippet.
- Select Insert Snippet followed by My Code Snippets.
- Pick the relevant snippet from the list, by clicking on it.
Right-click where you want to insert the code snippet and select Insert Snippet
Pick the relevant snippet from the list, by clicking on it
|