Extented separation of concerns and architecture of ASP.NET MVC 5 projects (Divide and conquer)

Most of the projects start as small projects and with time they turn into medium or even large projects. By the time that we realize this is happening, it might be too late and can cost us a lot to change the project architecture.

The separation of concerns is often neglected topic when dealing with web applications. Everyone who has created even once a basic web app knows that by default .NET has a decent template. Of course these templates follow the classic MVC architecture, which divides the application into three parts:
Model > View > Controller
That's okay for starter and for people that are new to these concepts, but if you want to create easily maintainable and extendable application you should absolutely put some effort to extend the basic MVC template. The aim of this blog post is to share a possible example of template extention.

...
...
Sample archicture and separation of concerns in ASP.NET Web Application

This extented template and more are available for download here .

What does this architecture give you more than the usual boilerplate templates?

(Those advantages are applicable for medium to large projects)
  • Easier development - one look at the project structure tells you where all different components are situated
  • Lower barrier for understanding, when new people are working on the project - when introducing new people to some project that is already in progress it's always better to do that step by step. And when these components are well structured and neat it is easier to go through them
  • Improved maintenance - whether you have created the project from scratch or not, when a problem occurs it's a lot easier to define where this problem comes from
  • Easier extension of the project - having all the components separated makes it a lot easier to extend them

Detailed explanation of the architecture

Data
  • Project for the database tables - contains the Db Context and the configurations of the migrations
  • Project for abstraction levels over the database - contains implemention of different abstraction levels over the database like Unit of work and Repository pattern
  • Project for the database models - contains all the db models including these from the ASP.NET identity which are moved from the web project
Services
  • Project for the services related to the database access - these services are not Web Api services, or any other ASP.NET services. They are just called like that. They might be called 'Providers',or whatever descriptive name you like. They are just regular classes plus interfaces that are responsible for the containment of the business logic of the application as well as the tasks related to CRUD operations over the database.
  • Project for the services related to the web operations - the same thing is valid here, but here are the services related to more complex logic that is not related to the database like Caching services, Email services and etc.
Tests
  • Project for the services tests - just to keep the different types of tests separately
  • Project for the controllers tests
  • Project for the routes tests
Tools
  • Here different console apps like Crawlers, Importers and etc. might be created
Web Tools
  • Project for the web application - this is the classic MVC project which is stripped of the Db context dependency as well as the db models dependencies . Contains configurations for the Dependency Injection, Automapper and other external libraries. The architecture is supposed to keep all your contoller actions very tiny and do all of your business logic in the services, which are injected by your IoC (inversion of control) container. In our case this is Autofac
  • Project for the web application infrastructure -this project contains source code which is related to the Web application, but might be reusable, and this is why it is separated by the Web App. For example here we can put our View Models, custom filters and annotations, html extention methods and helpers, and etc.
Lastly there is a separate project intendted to combine all the common classes between all the projects like Global Constants, Global Helper and etc.

So if you like this example architecture, and prefer not to start from scratch and save a couple of hours in boring configurations, don't hesitate and download it here .

View details »


Build real web app using .NET Core, Angular 5 and Template Stack templates (Part 3 - add to GitHub)

 Adding things to GitHub could be tricky at the beggining, espacially if you are not very familiar with the commands. In this third part of the topic how to 'Build real web app using .NET Core, Angular 5 and Template Stack templates (Part 3 - add to GitHub)' we will discuss how to it the right way. In order to upload to GitHub we will have to go through these steps:
  • Create GitHub account
  • Install Git bash or Git Shell. We will work with the console. Better to get use to it from the start
  • Create project to GitHub
  • Choose the right .gitignore file and modify it if needed. This is very important step, because we don't want to commit things like node modules, compiled javascript and etc.
  • Init the folder with your project as git repository
  • Add, commit and push the project
The first and second steps I will skip. I believe that everybody should have done that by now.
Creating GitHub project is also quite straightforward. Go to https://github.com/new, add your repository name, choose .gitignore for Visual Studio (very important) and go for 'Create repository'.
img
  Once you have the repository created fallow these steps:

First we will see how to set up Git repository directly in the folder where your source code is

  • 1.Go to your solution folder
  • 2.Open git bash or git shell in it
  • ...
  • 3.Type in - git init
  • 4. git remote add origin PATH/TO/REPO - get the path to repo from your new repository clone or download button
  • 5. git fetch
  • 6. git checkout -t origin/master
  • 7. git add .
  • 8. git commit -m "initial commit"
  • 9. git push - here you would probably be prompt to type in your GitHub credentials

How to set up Git repository coping the source code to another folder

  • 1. Go to empty folder
  • 2.Open git bash or git shell in it
  • 3.Type in - git clone PATH/TO/REPO
  • 4. Copy your project source code in this folder
  • 5. git add .
  • 6. git commit -m "initial commit"
  • 7. git push - here you would probably be prompt to type in your GitHub credentials
  Looks a bit scary at the beggining, but once you set it up it get's easier. Then you can only use up to 2-3 commands in your daily work.
You can check my repository with the application here https://github.com/bonchovylkov/TodoApp

View details »


Build real web app using .NET Core, Angular 5 and Template Stack templates (Part 2 - implement Todo app)

  This article is continuation of Part 1 - template review where we discussed how to download, sepup and use the Template Stack templates. Briefly the template that we are using has already implemented good architecture, database modifications, backend Token Authentication, cliend side login and regisred. The Angular is written in TypeScript and it's build using gulp.
  Now we want to implement the fallowing functionalities:
  • Adding Todo tasks, only by registered users
  • Listing of all user's tasks
  • Marking tasks as done
In order to implement the desired functionalities we have to do fallowing tasks
  • Backend-wise
  • Add new database table for the Todo tasks
  • Update the database with Code First Migration
  • Add new controller with a few API endpoints for adding, listing, or updating tasks (or so called CRUD operations)
  • Frontend-wise
  • Create new module, routing, and components for the Todo tasks
  • Create new service for the API calls
  • Add the new module and routing to the main modules
  • 1. Adding new table

    Adding new database table is as simple as adding new class and declaring it in the ApplicationDbContext:
    
     public class TodoItem : BaseDeletableModel<int>
        {
            [Required]
            public string Title { get; set; }
    
            public bool IsDone { get; set; }
    
            [Required]
            public string AuthorId { get; set; }
    
            public virtual ApplicationUser Author { get; set; }
        }
    
    
    The task has title, state (IsDone), and author, also it has the common properties (IsDeleted, DeletedOn, CreatedOn, ModifiedOn) shared between the classes due to the inherintance of BaseDeletableModel<int>
    In the ApplicationDbContext add collection of TodoItem
    
    
    public DbSet TodoItems { get; set; }
    
    
      Once you add this you can add code first migration from Tools -> NuGet Package Manager -> Package Manger Console. When you select this a window appear in which you have to type in the command:
    Add-Migration AddNewTableForTodoItems
    The first part is mandatory and the second is the name of the migration (which is by your choice). After a few seconds the new migration is scaffolded and you are ready to go with another command: Update-Database This is enough. At this point you will have your new table in the database. To be sure that everything went OK you can check your actual database if you have Management Studio.

    2. Add controller with CRUD operations

    
     public class TodoItemsController : BaseController
        {
            private readonly IDeletableEntityRepository repository;
    
            public TodoItemsController(IDeletableEntityRepository repository)
            {
                this.repository = repository;
            }
    
            [HttpGet]
            public IActionResult All()
            {
                var userId = this.User.GetId();
                var todoItems = this.repository.All().Where(t => t.AuthorId == userId).To().ToList();
    
                return this.Ok(todoItems);
            }
    
            [HttpPost]
            public async Task Create([FromBody]TodoItemBindingModel model)
            {
                if (model == null || !this.ModelState.IsValid)
                {
                    return this.BadRequest(this.ModelState.GetFirstError());
                }
    
                var todoItem = Mapper.Map(model);
                todoItem.AuthorId = this.User.GetId();
    
                this.repository.Add(todoItem);
                await this.repository.SaveChangesAsync();
    
                return this.Ok(Mapper.Map(todoItem));
            }
    
            [HttpPost]
            public async Task MarkAsDone(int id)
            {
                var todoItem = await this.repository.GetByIdAsync(id);
    
                if (todoItem == null)
                {
                    return this.NotFound();
                }
    
                if (todoItem.AuthorId != this.User.GetId())
                {
                    return this.Forbid(JwtBearerDefaults.AuthenticationScheme);
                }
    
                if (!todoItem.IsDone)
                {
                    todoItem.IsDone = true;
    
                    this.repository.Update(todoItem);
                    await this.repository.SaveChangesAsync();
                }
    
                return this.Ok();
            }
        }
    
    
      As you can see we are using directly the IDeletableEntityRepository interface, which is one of the implementations of the repository pattern which we mentioned in Part 1 - template review. Another aproach can be to create a TodoService but for simplicity we are using directly the repository here.The repository is being instantiate through the .NET Core dependency injection, so we are provided with the implementation of the interface in the constructor of the controller.
      In this controller we are creating three endpoints: one for the getting all user's tasks, one for adding new user task, and one for marking task as done with few validations.

    3. Creating modules, routing and angular components

      Looking at our desired functionalities we are goint to need at leats two components: one for adding and one for listing of the tasks.
    Moreover we can include these components in one bigger module which we can call user module, because we can enhance user functionalities with some new features. So awe going to create a folder containing UserModule, UserRoutingModule and one UserComponent with will contain our router-outlet directive. Inside this folder we will put our todo items in a nested folder.
    ...
    user.module.ts
    
    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormsModule } from '@angular/forms';
    import { UserRoutingModule } from './user.routes';
    import { USER_COMPONENTS } from './index'
    
    @NgModule({
        imports: [
            CommonModule,
            FormsModule,
            UserRoutingModule
        ],
    
        declarations: [USER_COMPONENTS]
    })
    
    export class UserModule { }
    
    user.routes.ts
    
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    import {
        TodoItemCreateComponent,
        TodoItemsComponent,
        UserComponent
    } from './index';
    
    import { AuthGuardService } from '../../services/index';
    
    const ACCOUNT_ROUTES: Routes = [
        {
            path: '',
            component: UserComponent,
            canActivate: [AuthGuardService],
            canActivateChild: [AuthGuardService],
            children: [
                { path: '', redirectTo: '/user/todo-items', pathMatch: 'full' },
                { path: 'todo-item-create', component: TodoItemCreateComponent },
                { path: 'todo-items', component: TodoItemsComponent }
            ]
        }
    ];
    
    @NgModule({
        imports: [RouterModule.forChild(ACCOUNT_ROUTES)],
        exports: [RouterModule]
    })
    
    
    export class UserRoutingModule { }
    
    user.component.ts and user.component.html
    As we said the UserComponent contains only the special router-outlet angular directive which manages in what part of the component the new routes will be included with their components.
    index.ts
    This file just combines and exports all the components from the module
    todo-item-create.component.ts
    
    import { Component } from '@angular/core';
    import { HttpErrorResponse } from '@angular/common/http';
    import { TodoItemsDataService, RouterService } from '../../../services/index';
    import { TodoItem } from '../../../domain/index';
    
    @Component({
        moduleId: module.id,
        selector: 'todo-item-create',
        templateUrl: 'todo-item-create.component.html'
    })
    
    export class TodoItemCreateComponent {
        constructor(private todoItemsDataService: TodoItemsDataService, private routerService: RouterService) { }
    
        public todoItem: TodoItem = new TodoItem();
        public errorMessage: string = null;
    
        public create(): void {
            this.todoItemsDataService.create(this.todoItem).subscribe(
                () => this.routerService.navigateByUrl('/user/todo-items'),
                (error: HttpErrorResponse) => this.errorMessage = error.error || 'Create TODO item failed.');
        }
    }
    
    
    In this component we can see the use of angular Injectable services, which help us to hide the more complex logic of sending http requests to the server and just handle the result of it. Besides that we see an object TodoItem which is just a rugular TypeScript class with a few properties in it.
    todo-item-create.component.html
    It's a regular html form, it is available on GitHub Repo here.
    todo-items.component.ts
    
    import { Component, OnInit } from '@angular/core';
    import { HttpErrorResponse } from '@angular/common/http';
    import { TodoItemsDataService } from '../../../services/index';
    import { TodoItem } from '../../../domain/index';
    
    @Component({
        moduleId: module.id,
        selector: 'todo-items',
        templateUrl: 'todo-items.component.html'
    })
    
    export class TodoItemsComponent implements OnInit {
        constructor(private todoItemsDataService: TodoItemsDataService) { }
    
        public todoItems: TodoItem[] = [];
        public errorMessage: string = null;
    
        ngOnInit() {
            this.todoItemsDataService.getAll().subscribe((data: TodoItem[]) => this.todoItems = data);
        }
    
        public markAsDone(todoItem: TodoItem): void {
            this.todoItemsDataService.markAsDone(todoItem.id).subscribe(
                () => {
                    this.errorMessage = null;
    
                    todoItem.isDone = true;
                },
                (error: HttpErrorResponse) => this.errorMessage = error.error || 'Mark TODO as done failed.');
        }
    }
    
    
    todo-items.component.html
    It's a regular html form, it is available on GitHub Repo here.

    4. Creating the TodoService (which we already used)

    todo-items-data.service.ts
    
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    import { Observable } from 'rxjs/Observable';
    
    import { TodoItem } from '../../domain/todo-item';
    
    @Injectable()
    export class TodoItemsDataService {
        private static readonly URLS = {
            ALL: 'api/todoitems/all',
            CREATE: 'api/todoitems/create',
            MARK_AS_DONE: 'api/todoitems/markasdone/'
        };
    
        constructor(private httpClient: HttpClient) { }
    
        public getAll(): Observable {
            return this.httpClient.get(TodoItemsDataService.URLS.ALL);
        }
    
        public create(todoItem: TodoItem): Observable {
            return this.httpClient.post(TodoItemsDataService.URLS.CREATE, todoItem);
        }
    
        public markAsDone(id: number): Observable {
            return this.httpClient.post(`${TodoItemsDataService.URLS.MARK_AS_DONE}${id}`, null);
        }
    }
    
    
      The service wraps the http requests logic in a couple of functions and returns Observable object to which we are able to subscribe and manage the successfull or error states of the query.

    5. Combining everything in working example

    Now that we have done our new modules and componenets we have to incorporate them in the whole solution. This is very common when we speak for Angular. In simple words all new components and modules have to be declared in the main module.
      One of the ways we can do that is to make it using the main routing
    app.routes.ts
    
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    import { HomeComponent } from './components/index';
    
    export const APP_ROUTES: Routes = [
        { path: '', component: HomeComponent, pathMatch: 'full' },
    
        { path: 'account', loadChildren: 'app/components/account/account.module#AccountModule' },
        { path: 'user', loadChildren: 'app/components/user/user.module#UserModule' }
    ];
    
    @NgModule({
        imports: [RouterModule.forRoot(APP_ROUTES)],
        exports: [RouterModule]
    })
    
    export class AppRoutingModule { }
    
    and then we can add the AppRoutingModule as import of the main app.module.ts. This is absolutely enough, and now we should be able to add tasks, list them and mark them as done.
    Another thing worth mentioning are the Guards services that we use to restrict on the client side certain routes. For example in user.routes.ts we are using AuthGuardService which simply checks if there is registered user, and if there isn't any it redirects to the login page. –ěn the contrary when you are accessing login and register routes there is guard that checks for not logged in users only. Of course all these checks are only client side and can be easily manipulated, so everrthing should be validated once again on the server. If you want to download a working example you should check here .
    The next part of this tutorial is how to upload this to a source control system for example GitHub. You can check it here.

    View details »


    Build real web app using .NET Core, Angular 5 and Template Stack templates (Part 1 - template review)

      This first part of the article aims to familiarize you with the.Net Core and Angular templates of Template Stack, and what is already done and ready to be used. The next (Part 2 - implement Todo app) part contains the implementaion logic of sample Todo application.
      If you want to download the final version the the Todo app check here.
     If you are familiar with downloading and runnning a .NET Core project from Template Stack you can start immediately, if not you can check how to set up the project using npm, gulp and visaul studio. (takes 5 minutes)

     Creating real web application with new technologies like .Net Core and Angular 5 from scratch could be challenging task. You should be awered of all the web develepment components and initial setups which are usually done by the most advanced developers in the team.
     This is why it's good idea to have some easy to use and configure boilerplate template. Some developers use the Visual Stuido templates, some have their own templates which are used to. These solution have some serious shortcomings like for example VS templates usually consists of one single project and everything is put in there. If you want to have good separation of concerns you have to put each logically separable part in different project and you will lose time for that.
     If you choose your own project template usually it gets messy during the renaming of the projects, solution and the relations. It's possible that one can be good at it and do it fast, but still you wouldn't be faster than Template Stack, which does all that in 30 seconds.
    Template stack gives you great number of improvements which otherwise could take significant amount of time and effords. It gives you:

    • Proven project arhchitecture (or so called sepration of concerns) view here. It's written that it is MVC 5, but the architecture of the .NET Core templates is quite similar
    • Entity framework 'Code first' extented database models view here. This feature just applies some OOP principles over the database models and automatically handles them. For example it automatically sets the CreatedOn date and etc.
    • Implementation of Repository pattern to make the database access a bit more more abstract and easy.
    • Automapper extended use view here. Simplifies the work with the famous library Automapper
    • Backend token auhtentication.
        It consists of Register functionallity which is quite trivial and it's located in the AccountController and uses the default .Net Core user creation.
      The more interesting part is the Login functionallity which uses custom implemented Baerer Token Provider which is done by creating TokenProviderMiddleware, TokenProviderOptions, TokenProviderExtensions classes. The last one extends the IApplicationBuilder class and sets the middleware to it.
      Check in GitHub the complete implementation
      TokenProviderMiddleware
      
       public class TokenProviderMiddleware
          {
              private readonly RequestDelegate next;
              private readonly TokenProviderOptions options;
              private readonly Func> principalResolver;
      
              public TokenProviderMiddleware(
                  RequestDelegate next,
                  IOptions options,
                  Func> principalResolver)
              {
                  this.next = next;
                  this.options = options.Value;
                  this.principalResolver = principalResolver;
              }
      
              public Task Invoke(HttpContext context)
              {
                  if (!context.Request.Path.Equals(this.options.Path, StringComparison.Ordinal))
                  {
                      return this.next(context);
                  }
      
                  if (context.Request.Method.Equals("POST") && context.Request.HasFormContentType)
                  {
                      return this.GenerateToken(context);
                  }
      
                  context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                  return context.Response.WriteAsync("Bad request");
              }
      
              private static int GetClaimIndex(IList claims, string type)
              {
                  for (var i = 0; i < claims.Count; i++)
                  {
                      if (claims[i].Type == type)
                      {
                          return i;
                      }
                  }
      
                  return -1;
              }
      
              private async Task GenerateToken(HttpContext context)
              {
                  var principal = await this.principalResolver(context);
                  if (principal == null)
                  {
                      context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                      await context.Response.WriteAsync("Invalid email or password.");
                      return;
                  }
      
                  var now = DateTime.UtcNow;
                  var unixTimeSeconds = (long)Math.Round(
                      (now.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);
      
                  var existingClaims = principal.Claims.ToList();
      
                  var systemClaims = new List
                  {
                      new Claim(JwtRegisteredClaimNames.Sub, principal.Identity.Name),
                      new Claim(JwtRegisteredClaimNames.Jti, await this.options.NonceGenerator()),
                      new Claim(JwtRegisteredClaimNames.Iat, unixTimeSeconds.ToString(), ClaimValueTypes.Integer64)
                  };
      
                  foreach (var systemClaim in systemClaims)
                  {
                      var existingClaimIndex = GetClaimIndex(existingClaims, systemClaim.Type);
                      if (existingClaimIndex < 0)
                      {
                          existingClaims.Add(systemClaim);
                      }
                      else
                      {
                          existingClaims[existingClaimIndex] = systemClaim;
                      }
                  }
      
                  var jwt = new JwtSecurityToken(
                      issuer: this.options.Issuer,
                      audience: this.options.Audience,
                      claims: existingClaims,
                      notBefore: now,
                      expires: now.Add(this.options.Expiration),
                      signingCredentials: this.options.SigningCredentials);
      
                  var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
      
                  var response = new
                  {
                      access_token = encodedJwt,
                      expires_in = (int)this.options.Expiration.TotalMilliseconds,
                      roles = existingClaims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value)
                  };
      
                  context.Response.ContentType = GlobalConstants.JsonContentType;
                  await context.Response.WriteAsync(JsonConvert.SerializeObject(response));
              }
          }
      
      TokenProviderOptions
      
       public class TokenProviderOptions
          {
              public string Path { get; set; } = "/token";
      
              public string Issuer { get; set; }
      
              public string Audience { get; set; }
      
              public TimeSpan Expiration { get; set; } = TimeSpan.FromDays(15);
      
              public Func> NonceGenerator { get; set; } = () => Task.FromResult(Guid.NewGuid().ToString());
      
              public SigningCredentials SigningCredentials { get; set; }
          }
      
      TokenProviderExtensions
      
      
          public static class TokenProviderExtensions
          {
              public static void UseJwtBearerTokens(
                  this IApplicationBuilder app,
                  IOptions options,
                  Func> principalResolver)
              {
                  ValidateArgs(app, options, principalResolver);
      
                  app.UseMiddleware(options, principalResolver);
      
                  app.UseAuthentication();
              }
      
              private static void ValidateArgs(
                  IApplicationBuilder app,
                  IOptions options,
                  Func> principalResolver)
              {
                  if (app == null)
                  {
                      throw new ArgumentNullException(nameof(app));
                  }
      
                  if (options?.Value == null)
                  {
                      throw new ArgumentNullException(nameof(options));
                  }
      
                  if (principalResolver == null)
                  {
                      throw new ArgumentNullException(nameof(principalResolver));
                  }
              }
          }
      

      All of these are used in the Startup class.
    • Angular client which is located in the app folder of the Web Project of the template. The client uses TypeScript , systemjs for module loader and gulp for tasks automation like moving files, compiling the TypeScript and Sass or Less, setting up the node packages, bundling and minifing and etc.
      There is sample architecture included which starts with AppComponent and it's loading the home component by default. The client also has already implemented baerer authentication. The implementation consists of Account Module with it's own routing and a couple of components for login and registration. The routing implementation:
      account.routes.ts sets the path to the components
      
      
       import { NgModule } from '@angular/core';
      import { Routes, RouterModule } from '@angular/router';
      
      import {
          AccountComponent,
          LoginComponent,
          RegisterComponent
      } from './index';
      
      import { AuthNoGuardService } from '../../services/index';
      
      const ACCOUNT_ROUTES: Routes = [
          {
              path: '',
              component: AccountComponent,
              canActivate: [AuthNoGuardService],
              canActivateChild: [AuthNoGuardService],
              children: [
                  { path: '', redirectTo: '/account/login', pathMatch: 'full' },
      
                  { path: 'login', component: LoginComponent },
                  { path: 'register', component: RegisterComponent }
              ]
          }
      ];
      
      @NgModule({
          imports: [RouterModule.forChild(ACCOUNT_ROUTES)],
          exports: [RouterModule]
      })
      
      export class AccountRoutingModule { }
      
        Here is also example of the use of so called Guards which are intented to verify (only cliendside) if the current user has certain authorization rights. In our case AuthNoGuardService checks if the user is registered or not and if it's registered it's doesn't allow him to go login or register.
        It worth mentioning the implementation of the service (as you see there is also client side service) which is responsible for the authentication. This AuthService does the actual queries to our API backend which we have previously set up.
      Also the AuthService keeps track of current authentication state of the user through BehaviorSubject which is an object that has certain behavior for example it can say rather the current user is authorized or not.
      Inside this service is used the IdentityService which parses the information from the login response and gets the email, the token, the expiration date and the roles of the current user which are stored locally in the localStorage of the user's browser.
    If you feel confident with this first part you can continue with next (Part 2 - implement Todo app) where we are building on top of currently discussed things. If you want to download the final version the the Todo app check here.

    View details »


    Fast and interactive API documentation with Swagger



    Creating an API documentation when working with any kind API framework is almost mandatory.
    Of course except if you are not the only one who is using the API endpoints, it that case don't read this... Otherwise you should.

    Doing the documentation manually can be a annoying and continues work. By continues I mean that it's not enough to create the documentation once And leave it like this forever..

    This is why this is not a good approach if you value your time and efforts. The developers are always looking for the easiest and smarter way of doing things.
    Here I will present you how can you do your full API documentation, with the minimum effort of installing NuGet package and adding a few lines of code.

    *If you hate to read badly written text in English and want to get to the action and see how is implemented in a project. Check this link with implementation of swagger

    The NuGet package is called Swashbuckle and the version that the example is using is 4.0.0 and it's done with MVC 5.

    When install this package in your web project you will be automatically provided with a configuration file called SwaggerConfig placed in App_Start folder.
    You will have to update this file to like this:

    
     public class SwaggerConfig
        {
            public static void Register()
            {
    
                Swashbuckle.Bootstrapper.Init(GlobalConfiguration.Configuration);
    
                // NOTE: If you want to customize the generated swagger or UI, use SwaggerSpecConfig and/or SwaggerUiConfig here ...
    
                SwaggerSpecConfig.Customize(c =>
                {
                    var path = GetXmlCommentsPath();
                    if (!File.Exists(path))
                    {
                        XmlDocument doc = new XmlDocument();
                        XmlNode Root = doc.AppendChild(doc.CreateElement("doc"));
                        doc.Save(path);
                    }
                    
                    c.IncludeXmlComments(path);
                });
    
            }
    		
            protected static string GetXmlCommentsPath()
            {
    
                return System.String.Format(@"{0}\bin\CarsApp.Web.XML", System.AppDomain.CurrentDomain.BaseDirectory);
            }
        }
    	
    Example of SwaggerConfig file

    This method Register() is called automatically when the project is started. So you don't have to do anything else.
    Doing that is absolutely enough and you can start using your documentation. You will be able to find it at:
    • locally - localhost:{port}/swagger
    • live - {your domain}/swagger
    The result that you will get is pretty good interface containing expandable tabs for each different API controller.
    • Within each tab (controller) are it's methods. (or API endpoints).
    • Moreover there is a description on each endpoint parameters.
    • Also there is a 'Try It Out' button which makes a call to the endpoint, which is great for debugging.

    swagger-screenshot


    *Again if you want to use it directly in a prepared template. You can get it here

    Check out our 3 minute Swagger Video!

    View details »


    Autofac Dependancy Injection use and configuration

    The 'Dependancy Injection' or also called 'Inversion of control containers' is a design pattern that allows us to create more abstract applications and use Interfaces instead of instances of classes. It sounds a little bit scary at the beginning, but in the modern frameworks is actually just a simple configuration. Even it is integrated in some of the most recent frameworks like .NET Core and Angular 4.

    You can download a template with the implementation here!

    This concept is strongly related to the Object oriented programming and it aims to help us with a couple of things:
    Firstly, we no longer depend on specific implementation of a class, and this allows the components to be tested through mocking of dependencies.
    Also we can swap dependency implementations in different environments.
    Our code becomes loosly coupled
    Promotes logical abstraction of components
    In old MVC 5 .Net applications the Dependancy Injection is not integrated and you have to install NuGet Package like Autofac or Ninject or something similar.
    For our MVC5 templates we use Autofac.
    When istall it from the package manager it comes with a AutocafConfig file. Of course it has a default configurations but we have added a few more.

    
     public static class AutofacConfig
        {
            public static void RegisterAutofac()
            {
                var builder = new ContainerBuilder();
    
                // Register your MVC controllers.
                builder.RegisterControllers(typeof(MvcApplication).Assembly);
    
                // OPTIONAL: Register model binders that require DI.
                builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
                builder.RegisterModelBinderProvider();
    
                // OPTIONAL: Register web abstractions like HttpContextBase.
                builder.RegisterModule();
    
                // OPTIONAL: Enable property injection in view pages.
                builder.RegisterSource(new ViewRegistrationSource());
    
                // OPTIONAL: Enable property injection into action filters.
                builder.RegisterFilterProvider();
    
                // Register services
                RegisterServices(builder);
    
                // Set the dependency resolver to be Autofac.
                var container = builder.Build();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            }
    
            private static void RegisterServices(ContainerBuilder builder)
            {
                builder.Register(x => new ApplicationDbContext())
                    .As()
                    .InstancePerRequest();
                builder.Register(x => new HttpCacheService())
                    .As()
                    .InstancePerRequest();
                builder.Register(x => new IdentifierProvider())
                    .As()
                    .InstancePerRequest();
    
                builder.RegisterType().As().InstancePerRequest();
    
                builder.RegisterAssemblyTypes(typeof(ICommonService).Assembly)
               .Where(t => t.Name.EndsWith("Service"))
               .AsImplementedInterfaces().InstancePerRequest();
    
                //this one is in another assembly
                builder.RegisterAssemblyTypes(typeof(ILoggingService).Assembly)
                 .Where(t => t.Name.EndsWith("Service"))
                 .AsImplementedInterfaces().InstancePerRequest();
    
                builder.RegisterGeneric(typeof(DbRepository<>))
                    .As(typeof(IDbRepository<>))
                    .InstancePerRequest();
    
                builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                    .AssignableTo().PropertiesAutowired();
            }
        }
    

    Most of this code comes by default when we install the Autofac package. All we have to do is to register our dependencies in the RegisterServices method.
    This can be done in a couple of ways. Firstly you can register your services one by one. I don't recomend that but sometimes it's the only way. Like in cases when you don't follow some inner convention like the one introduced in our templates.
    The convention is simple. Just create a tuple of Interface and class that implements the interface and name them Equally, with the ecxeption of the "I" prefix of the interface, and also make them end up with "Service" suffix.
    Doing that you can make an example of a tuple in RegisterServices and tell the container to follow this convention for all similar tuples in the same Assembly. Like in this example.
    
    builder.RegisterAssemblyTypes(typeof(ICommonService).Assembly)
               .Where(t => t.Name.EndsWith("Service"))
               .AsImplementedInterfaces().InstancePerRequest();
    
    Beside that you have an option to set up the type of the instace that you will be provided with. In the following example we get new instance for each new Request.
    builder.RegisterType().As().InstancePerRequest();

    You have a couple more options like creating a Single Instance (or so called Singleton).
    builder.RegisterType().As().SingleInstance();
    It depends on what you are tring to achieve.
    Moreover you can tell that some class can have autowired properties, which is proven as very useful for base classes, and this is why is set up here.
    
    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                    .AssignableTo().PropertiesAutowired();
    
    As I mentioned in the new .Net Core you have integrated 'Dependancy Injection' and just have to do the 'RegisterServices' configurations and that is all.
    You can download a template of a .NET Core application here!

    View details »


    Automapper extended use

    What does Automapper do?


    It saves you time mapping properties with same names and types, by doing that automatically for you. You just have to tell the library which class can me mapped to another and etc.
    ...

    Adding the 'Automapper' nuget package is super easy, just find it and istall it. This is why you are probably thinking why is this even mentioned as a 'Feature' of the template, but there is more to it.
    *These custom configurations are made for Automapper version 3.3.1, but might be refactored easy for the lattest versions

    You can download the template with the implementation here!
    We don't consider installing the nuget package as a feature but the follow up configurations of the mappings, without which usually the projects end up with a couple of huge files describing mappings between classes. This is exactly what we are preventing when adding additional configurations to it.

    Lets see how can we do that.
    We have to add AutomapperConfig class and couple of interfaces like IMapFrom and IHaveCustomMappings.
    
     public class AutoMapperConfig
        {
            public static void Execute()
            {
                var types = Assembly.GetExecutingAssembly().GetExportedTypes();
    
                LoadStandardMappings(types);
    
                LoadCustomMappings(types);
            }
    
            private static void LoadCustomMappings(IEnumerable types)
            {
                var maps = (from t in types
                            from i in t.GetInterfaces()
                            where typeof(IHaveCustomMappings).IsAssignableFrom(t) &&
                            !t.IsAbstract &&
                            !t.IsInterface
                            select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();
    
                foreach (var map in maps)
                {
                    map.CreateMappings(Mapper.Configuration);
                }
            }
    
            private static void LoadStandardMappings(IEnumerable types)
            {
                var maps = (from t in types
                            from i in t.GetInterfaces()
                            where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) &&
                            !t.IsAbstract &&
                            !t.IsInterface
                            select new
                            {
                                Source = i.GetGenericArguments()[0],
                                Destination = t
                            }).ToArray();
    
                foreach (var map in maps)
                {
                    Mapper.CreateMap(map.Source, map.Destination);
                    Mapper.CreateMap(map.Destination, map.Source);
                }
            }
        }
    
        public interface IHaveCustomMappings
        {
            void CreateMappings(IConfiguration configuration);
        }
    
         public interface IMapFrom
            where T : class
        {
        }
    
    
    This method execute should be called on ApplicationStart in the Global.cs file.
    What this source code gives us neatly and clean way to create mapping between the classes.

    Here is an example of the creation of the mappings this way.
    
    public class TSFeatureViewModel : BaseViewModel, IMapFrom, IHaveCustomMappings
    {
    
    
            public string Name { get; set; }
    
            public string Description { get; set; }
    
            public string Link { get; set; }
    
            public string ImplementationDetails { get; set; }
    
            public decimal? AddedValue { get; set; }
    
            public string VideoUrl { get; set; }
    
            public int? ParentFeatureId { get; set; }
    
            public string ParentFeature { get; set; }
    
            public void CreateMappings(IConfiguration configuration)
            {
                configuration.CreateMap()
                 .ForMember(m => m.ParentFeature, opt => opt.MapFrom(t => t.ParentFeature != null ? t.ParentFeature.Name : null))
                 .ReverseMap();
            }
     }
    
    When we implement the IMapFrom interface with generic argument of the source class we enable mappings between the properties with similar names and types.
    In case that we have properties that are called differently we have the Ihavecustommappings interface which makes us implement a mehtod called CreateMappings and point out manually which property have to be mapped to which.

    If you want to see the '3 minute' video about these configurations :

    Download the template here!

    View details »


    Sample example of Generic Repository in .NET? Why and how?

    Creating some kind of abstraction over the database is almost mandatory when talking about a real project.
    In general when talking about web applications the interactions to the database are down to :
    • Create
    • Read
    • Updated
    • Delete
    Or so called CRUD operations.
    If we decide not to create repositories and use the database context directly it might turns out that we are not fallowing the best OOP practices, because on each database operation we would be doing a couple of repeations in the code. For small applications this might be accepted, but if the applications tend to grow it's highly recommended to use some implementation of the famous Repository pattern. There are a few ways that we can step into:
    • Create separate class (repository) for each database table
    • Create generic repository

    The first approach is not our topic now, so i just gonna mention that is it perfectly okay to use it if you want. It gives more freedom and Entity specific actions, but that comes with a price of a lot more source code. More specifically you would have as much repositories as the entities of your database. And they can be a lot. This is why personally I prefer not to use it in this basic form and in this blog post as you already know we will stop our attention to the sample implementation of generic repository pattern.

    Left start with some source code of the generic repository interface: (I presume that you are familiarized with the 'Extedned database concept' through generic base model. If you are not you can check it out here
        public interface IDbRepository<T> : IDbRepository<T, int>
            where T : BaseModel<int>
        {
        }
    
        public interface IDbRepository<T, in TKey>
            where T : BaseModel<TKey>
        {
            IQueryable All();
    
            IQueryable All(string[] includes);
    
            IQueryable AllWithDeleted();
    
            T GetById(TKey id);
    
            void Add(T entity);
    
            void Delete(T entity);
    
            void HardDelete(T entity);
    
            void Save();
        }

    The bottom interface is absolutely generic and can be used with any 'BaseModel' class, which has any type of it's Id, by any i mean string or some numerical type.

    View details »


    Entity framework 'Code first' extented database models

    If you use Entity framework Code first approach of database creation you should definetely read this article.
    Personally, as a backend developer, I have created a lot of databases - at the begining for exersice, subsequently for real projects at work.
    At some point the code first approach has proved itself as the best option when dealing with web development for a couple of reasons.
    • Firstly we may not be good at SQL at all, but still be able to create a decent database quickly and easily (which is highly inadvisable in my opinion, but it's possible) just by knowing the main concepts for the relationships between the tables (classes)
    • Secondly we can reuse our knowledge in OOP
    • Lastly the distribution is a lot easier using this approach (you don't have to script databases and etc.)

    Now to the point!

    If you have created code first databases more than a couple of times and you are good at object oriented principles you have to realize that there is something 'smelly' going on over there:
    we have common properties between our models
    So what do we do. Of course we are good at OOP so we create a Basic database model that will hold all of our common properties. But what should we put in it.
    Here is a possible example:
     public abstract class BaseModel : IAuditInfo, IDeletableEntity
        {
            [Key]
            public TKey Id { get; set; }
    
            public DateTime CreatedOn { get; set; }
    
            public DateTime? ModifiedOn { get; set; }
    
            [Index]
            public bool IsDeleted { get; set; }
    
            public DateTime? DeletedOn { get; set; }
        }
    
    And because we follow the OOP good practices we create our interfaces : IAuditInfo, IDeletableEntity

      public interface IAuditInfo
        {
            DateTime CreatedOn { get; set; }
    
            DateTime? ModifiedOn { get; set; }
        }
    The IAuditInfo interface guarantees that all of our database records will be neatly accounted and we will know when each record has been created and modified.

      public interface IDeletableEntity
        {
            bool IsDeleted { get; set; }
    
            DateTime? DeletedOn { get; set; }
        }
    The IDeletableEntity interface follows a practice that says that nothing should be deleted from the database, but only marked as deleted.

    That's great, now all of our models will hold these common properties.

    But something is missing

    It's possible and this is how it's done
        public override int SaveChanges()
            {
                this.ApplyAuditInfoRules();
                return base.SaveChanges();
            }
    
            private void ApplyAuditInfoRules()
            {
                // Approach via @julielerman: http://bit.ly/123661P
                foreach (var entry in
                    this.ChangeTracker.Entries()
                        .Where(
                            e =>
                            e.Entity is IAuditInfo && ((e.State == EntityState.Added) || (e.State == EntityState.Modified))))
                {
                    var entity = (IAuditInfo)entry.Entity;
                    if (entry.State == EntityState.Added && entity.CreatedOn == default(DateTime))
                    {
                        entity.CreatedOn = DateTime.UtcNow;
                    }
                    else
                    {
                        entity.ModifiedOn = DateTime.UtcNow;
                    }
                }
            }
    This block of code should be put in your database context class and it maintans the IAuditInfo interface properties itself.
    Now you probably think:
    but wait...how about these things for the 'not deleting anything practice', we still have to filter all the deleted things whenever we make query to the database?
    And you would be absolutely right, to ask this! But there is a solution to this also.
    And the solution is to implement a Repository pattern, like an abstraction level over the database. Here is an example:
        public class DbRepository : IDbRepository
            where T : BaseModel
        {
            public DbRepository(DbContext context)
            {
                if (context == null)
                {
                    throw new ArgumentException("An instance of DbContext is required to use this repository.", nameof(context));
                }
    
                this.Context = context;
                this.DbSet = this.Context.Set();
            }
    
            private IDbSet DbSet { get; }
    
            private DbContext Context { get; }
    
            public IQueryable All()
            {
                return this.DbSet.Where(x => !x.IsDeleted);
            }
    
    
            public virtual IQueryable All(string[] includes)
            {
                var data = this.DbSet.AsQueryable();
                for (int i = 0; i < includes.Length; i++)
                {
                    data = data.Include(includes[i]);
                }
    
                return data;
            }
    
            public IQueryable AllWithDeleted()
            {
                return this.DbSet;
            }
    
            public T GetById(int id)
            {
                return this.All().FirstOrDefault(x => x.Id == id);
            }
    
            public void Add(T entity)
            {
                this.DbSet.Add(entity);
            }
    
            public void Delete(T entity)
            {
                entity.IsDeleted = true;
                entity.DeletedOn = DateTime.UtcNow;
            }
    
            public void HardDelete(T entity)
            {
                this.DbSet.Remove(entity);
            }
    
            public void Save()
            {
                this.Context.SaveChanges();
            }
    
    
        } 
    This way when we make a query to the database we can easily filter all the deleted items, and that wouldn't affect us at all.
    Moreover we can make a delete method that do all the requeired steps to make database entity to be 'marked as deleted'.

    View details »