Generate Layered ASP.NET MVC Web Applications

By | July 15, 2013

I created a generator which generates Business and Data Access functionalities based on your domain model. I’ve build this generator + template because I think it makes sense even in smaller web applications to structure the code well. Also when the web application is very simple we never know which requirements we encounter in the future.
The advantages of my generator and template are:

  • Code generation based on domain model. (Saves you time!)
  • Flexibility. The generator creates partial classes. You can easily extend them.
  • Seperation of concerns.
  • Testability. No direct instantiation of objects. Abstraction with interfaces.
  • Concentrate on the core (Business, UI) of your application.
  • Running application in few minutes!

The solution template contains following projects:

WebUI ASP.NET MVC project.
Business Contains the domain model and the business logic.
DataAccess Data access with ADO.NET EF Code First approach.
Bootstrapper Boostrapping. (Dependency Injection with StructureMap)


T4 Generator Architecture

How does it works?
Prerequisite:

1)
Download the solution from GitHub. https://github.com/dmicic/Dmicic.Template.ApplicationGeneration
(You need only the “Templify” folder.”)
2)
Open the SetupProject.cmd and set the “DestinationFolder”, “TemplateFolder” and “SolutionName” variables.
AppGen SetupProject.cmd
Now run the SetupProject.cmd file.

3)
AppGen Domain Model
Open the solution and define your domain models (in this tutorial “Person.cs”) in the Business project under the folder “Domain”. Then execute the “App_Generator.tt” file. This file generates in this example following files:
Dmicic.WebShop.DataAccess (under .generated folder)

PersonConfiguration.generated.cs ADO.NET EF entity type configuration for Person domain model.
ObjectContext.generated.cs ADO.NET EF DbContext class.
PersonRepository.generated.cs Generic repository class for Person domain model.

Dmicic.WebShop.Business (under ApplicationService\.generated folder)

IPersonRepository.generated.cs Person repository interface. (Implementation is in Dmicic.WebShop.DataAccess project)
IPersonApplicationService.generated.cs Person application service interface contract.
PersonApplicationService.generated.cs Person application service implementation.

4)
The base classes for the repositories and application services contains CRUD functionalities. If you need additional functions you can create a partial class for the appropriate domain model repository or application service.
Here is an example: I’ve created a partial interface “IPersonApplicationService” and a class “PersonApplicationService” in the folder Dmicic.WebShop.Business\ApplicationService.

public partial class PersonApplicationService
{
    public IEnumerable<Person> FindByFirstname(string firstname)
    {
        return this.Repository.GetByCondition((person) => person.Firstname == firstname);
    }
}

public partial interface IPersonApplicationService
{
    IEnumerable<Person> FindByFirstname(string firstname);
}

5)
Now build your application. I recommend to inject the application services. In this example the services are passed as constructor parameters automatically. Here is an example of a simple ASP.NET MVC Controller.

public class SearchController : Controller
{
    private IPersonApplicationService Service { get; set; }
    private IUnitOfWork UnitOfWork { get; set; }

    public SearchController(IUnitOfWork unitOfWork, IPersonApplicationService service)
    {
        this.UnitOfWork = unitOfWork;
        this.Service = service;
    }

    public ActionResult Index()
    {
        var foundPeople = this.Service.FindByFirstname("Darko");
        return this.View(foundPeople);
    }

    public ActionResult SaveSomething()
    {
        // Start transaction. (Optional)
        using (var tx = this.UnitOfWork.StartTransaction())
        {
            var person1 = this.Service.Create();
            person1.Id = Guid.NewGuid();
            person1.Firstname = "Firstname 1";
            person1.Lastname = "Lastname 1";

            this.UnitOfWork.Commit();
            tx.Complete();
        }

        return this.View();
    }
}

When you run the web application, the ObjectContext installs the Database and querying etc will work from the first compile! 😉

Have fun with the generator/template.
Feedback is appreciated!