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 »


Get started with Basic Core Template With Angular for Visual Studio

For starter let mention again the prerequirements:

...
You will need to have Windows installed to run this project, preferably latest version. Then on top of that you have to have VIsual Studio 2017 with latest updates possibly. Up to this point you will be able to open your project, but still you wouln't be able to run it.
The project works with SQL Database, so you will need to have SQL server installed, SQL Express is a great free solution.
The rest of the program stack that you need to have installed concerns the client side part of the project.
Download and install NodeJs server if you don't have it yet. Once you have it, you can install npm, which is the package manager of node. Once you have npm you can install Gulp, which is a npm package. The last three components are strongly connected as you can see. They have to be installed in the described order.

Let's assume that you got that covered (without installing gulp) and continue with final steps.

  • Open Cmd (might need to open it as Administratior) and type npm install gulp -g, which will install the gulp package globally
  • Locate the zip folder of the solution, and extract it
  • Enter the Web Project folder in the File explorer
    ...
  • Open Cmd and navigate to the same folder, or just press Shift + Right Click and choose Open Cmd (or PowerShell) here and type npm install and after a few minutes you will have a new folder containing the node packages called node_modules
    ...
  • After you have this type gulb build wait for a minute and wwwroot folder will be created for you
    ...
  • Open Visual Studio 2017 -> File -> Open -> Project/Solution and find your newly extracted project
  • After the solution opens it will start automatic NuGet package restore, wait a bit then Build the solution
  • When the build is successful check appsettings.json for your connection string validity. Check point 5 from this article about more information: How to run template
  • Run the web project, and you will be able Login, Register and create TODO records

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 »