Setting AutoMapper to our Project
In this lesson, we're going to add AutoMapper to our project
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the The newline Guide to Fullstack ASP.NET Core and React course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to The newline Guide to Fullstack ASP.NET Core and React with a single-time purchase.

[00:00 - 00:17] We prepared our DTOs in the last lecture and I noticed that the last updated property setting the time.now so we can get rid of it because we will get it from the database. Now we need something that can map our original entity with DTOs.
[00:18 - 00:23] Nothing can be better than automapper to do this job. We need to add this package to our API project.
[00:24 - 00:48] So let's open the nougat package, "calorie" and click on "nougat gallery". Now here, and search for the package which is going to be the best use case for us type "auto-mapper.extensions" and we already see it.
[00:49 - 00:56] This is "automapper.extensions.microsoft.dependency injection". We want to install it to our API project.
[00:57 - 01:07] So check that box and click on "install". And that is done.
[01:08 - 01:28] To make sure it is restored, what we can do is go inside the API project and type "dotnet .test" and type "restop". Inside our API project, we can create a new folder for all the helpers we are going to use and "automapper" is one of the helpers.
[01:29 - 01:42] Let's create a new folder and let's call it "helpers". Inside we need a class where we will map our entities to the DTOs.
[01:43 - 01:54] Let's call this file "mapping profiles". And of course it's going to be a class.
[01:55 - 02:08] The class will derive from profile which will be provided by "automapper". So I will write "profile" and let's import it using "automapper".
[02:09 - 02:19] Now we need an empty constructor so let's do that as well. Generate constructor mapping profiles.
[02:20 - 02:26] Inside mapping profiles, we are going to do the mapping. So we can write "create map".
[02:27 - 02:45] With angle brackets, we need to mention classes we want to map together. We have prepared our cost DTO so we can map "force with force DTO" and close it with brackets.
[02:46 - 02:59] And we have mentioned type string for our category so we need to get that property from the category table. We can write "dot for member" and brackets.
[03:00 - 03:14] We want to map our category property so we can write "c" which is for the "c ourses" table and "c.category" which is the property and a comma. We want this to map from the category table with "name property".
[03:15 - 03:24] So we can write "o" which goes to "o.map" and inside we want to get "category. name".
[03:25 - 03:44] So let's get another variable "s.category.name". Now we want to import "course from entity and cost DTO using API. DTO".
[03:45 - 04:11] Now what it will do is map the properties with the same name easily and since we want to get the category name for the category property which is a string now it will go to the category table and get the name property for us and that's really it. Now what we can do is we also need to map the learning to learning DTO and requirement to requirement DTO.
[04:12 - 04:41] So let's do the same thing, create map, angle brackets, requirement, requirement DTO and again create map, angle brackets, learning to learning DTO. Now let's go to the startup class and add "automapper" as a service.
[04:42 - 04:58] And "order" doesn't matter here so I can maybe read it here. "services.addautomapper" and then we will mention the assembly of it.
[04:59 - 05:17] So type of and here I will mention the mapping profiles that we just created. We need to import mapping profiles using "api.helpers" and this is really it.
[05:18 - 05:23] We can now start using them in our controllers. So first of all let's go to our "courses" controller.
[05:24 - 05:36] Let's close everything and go to the "courses" controller. First of all we will inject "automapper" to our controller.
[05:37 - 05:48] Inside the constructor I can write "i.mapper" and I will simply call it "mapper ". "i.mapper" is the interface for "automapper".
[05:49 - 06:02] Let's import it using "automapper" and initialize field from parameter. Then we can go down to get "courses" method.
[06:03 - 06:17] Instead of directly returning the "courses" what we can do is we can write "m apper.map". Then we can mention what we are mapping from and what we are mapping to.
[06:18 - 06:24] So I will use the angle brackets. Since I want to map from "I read only list of course".
[06:25 - 06:58] So I will write "I read only list of type course" and I want to map it to "I read only list of course. DTO and here I will mention "courses".
[06:59 - 07:17] We don't have "course.to" so let's import it using "api.dto" and also we'll have to replace "course" with "course.to" since now we are returning "course.to". Same way in the "get cos" method let's first of all change "course.to".
[07:18 - 07:53] "course.to". Let's create a new variable called "course" which will store the data and now rather than returning the whole of it we want to return the "course.to". So what we can do is return "mapper.map" and we want to map "course.to.course.t to" and we will mention the data source which is "course".
[07:54 - 08:09] We are good to go now what we can do is start our server.net once run. Now we can open postman to check if it's working properly.
[08:10 - 08:26] First of all let's check "get cos" method and now we'll see the data. I will copy this "id" to check if the "get cos" method is working properly.
[08:27 - 08:38] So what I can do is go to "get cos" and use this "id" to see if it is working fine. And now we see everything and we see the name as well.
[08:39 - 08:42] Also, the learnings. So this is amazing.
[08:43 - 08:59] We don't see our requirements and learnings because inside our course repository we haven't added eager loading for requirements and learnings. So that is the reason but we see it for "get cos" by idasync method which is perfect.
[09:00 - 09:10] Now for a moment let's think what we want in our categories response. I don't want to see all the associated courses when the list of categories is called.
[09:11 - 09:20] But when an individual category is called I would like to display all the associated courses as well. Let us create another DTO.
[09:21 - 09:36] Let's go to the API project and inside DTO I will create a new class and I will call it category DTO. It will be same as the category entity but instead of returning "cos" we will return "cos" to "to".
[09:37 - 09:56] So what I'll do is I'll go to the category and now I don't want to return the " cos" because the "cos" has category and the category has "cos". So we don't want that circular dependency I will copy it and I will go back to the category DTO again and paste it here.
[09:57 - 10:12] But this time I will replace "cos" with "cos" "to" and let's import iCollection using system.collection.static and it's not DTO it's DTO. We need another one for categories.
[10:13 - 10:26] So let's call "categories DTO". This time we just want the ID and the name.
[10:27 - 10:57] So I can get rid of this because when I'm calling all the categories I don't care which category has which costs but when I'm calling it individually I want all the associated costs so that's why this categories DTO will only return the ID and the name and this way it also resolves the problem of circular dependency. Again what we'll do is go to mapping profile where all the mapping happens and we will create two more.
[10:58 - 11:26] The first one will be between category and category DTO and another one will be between category and categories DTO. Now the same way we will go to the categories controller.
[11:27 - 11:38] Let me first close everything go to the categories controller and inject iM apper. Let's for it.
[11:39 - 11:49] Napper. Let's import it using "automapper" and initialize field from parameter.
[11:50 - 12:23] Inside this category's method we will rather than returning the categories we will return maper.map and I want to map from ID only list of category to ID only list categories DTO. And we will mention the categories here.
[12:24 - 12:37] Now we need to replace category with categories DTO. Since we haven't imported it we will do it right here.
[12:38 - 13:07] And here we will replace category to category DTO and rather than returning the category here what we will do is maper.map and we will map the category to category DTO and we will mention category here. And that's simply it.
[13:08 - 13:17] Let's go to the postman to check this request as well. Now in module 3 click on get categories and click on send.
[13:18 - 13:28] Now we see ID and name because when I'm calling all the categories I just want ID and the name. But if you call the category let's call it with ID 1.
[13:29 - 13:38] Oh we see an error. Dot auto maper mapping exception missing type map configuration or unsupported mapping.
[13:39 - 13:58] I think we need to go to our mapping profiles to see what happens. Oh oh we have added this categories DTO twice so I will change it to category D TO and refresh it and let me open that request again and click on send.
[13:59 - 14:11] At this time I received the ID name and collection of cost ETO as well. Since our cost ETO doesn't have requirements and learnings we are not seeing them here.
[14:12 - 14:17] And that's perfect. I think now you understand how this includes statement works.
[14:18 - 14:34] But my point is if we have like a lot of controllers we don't want to repeat this process again and again right. We don't want to create different repositories you know creating different interfaces and then using the include statements every time.
[14:35 - 14:44] We have a solution for this and that is called generic repository. So let's find that out what generic repository is in the next section.