Nuget package, how to not commit all libraries to your source control

I am publishing more and more code to GitHub when I am posting blog post to have something to the reader to test. The problem is that if I want to have something that works, I need to have all references published into the source control. This can start to be huge if I have several packages. Nuget gives three advantage to not have these libraries into the source control.

  • Source control include every version of every file within the repository, and binary files that are updated frequently can lead to significant repository bloat and more time required to clone the repository.
  • With the packages included in the repository, team members may add references directly to package contents on disk rather than referencing packages through NuGet.
  • It becomes harder to “clean” your solution of any unused package folders, as you need to ensure you don’t delete any package folders still in use.

But, how can we send a project into a repository and have NuGet knows that it needs to download every references on the first build? This can be done by changing the solution to use NuGet Package Restore. To enable this feature, right click the solution in the Solution Explorer and select Enable Restore NuGet Package Restore.
EnableNuGetPackageRestore
This will create a folder named .nuget with 3 files.nugetfiles

This will install all referenced packages before a project is built, thereby ensuring that all dependencies are available to a project without requiring them to be stored in source control!

Two NuGet Restore Approach

When NuGet Restore is enabled, you have two different option. The first one allow Visual Studio to download automatically the reference. This is the default approach and the recommended one. The second approach is the console one that is more manual.

Automatic Approach

The automatic approach is the default one since NuGet 2.7. When the code is compiled, Visual Studio raises an event that NuGet is hooked to. This allow NuGet in a pre-event to execute itself. NuGet reads the packages.config file and download every package not present. This mean that the first time you get the code that the build is slower. The speed is not reduced because of the compilation but because NuGet downloads every package. The second time you will compile, the speed will be back at only having the source code to compile. Of course, Visual Studio needs to have the option to download NuGet package. This can be found in the Tools>Option menu of Visual Studio.
PackageManagerPackageRestoreOptions

Manual Approach

As we have mentioned, NuGet added 3 files. One is an executable called NuGet.exe that can be called manually to download package from the packages.config. Here is an example of the command you can write to get every files.

nuget.exe restore YourSolutionFile.sln

I recommend you to read the NuGet console command.

Using Transaction with WCF Services

If you need to call two different WCF service and be sure that both are successful before committing, you’ll need to use transaction. This will require that both service’s operation contain the attribute TransactionFlow with the option to Allowed. Many other option could have been possible. NotAllowed is when you do not want to be part of transaction, which is the default value. Allowed allows to participate in a transaction if the client specify in his code a transaction scope. Finally, mandatory force that the operation is called within a transaction scope.

[ServiceContract]
public interface IServiceContractOne
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    void Method1();
}

The next step is the implementation of this contract. The method Method1() that has the TransactionFlow attribute needs to have also an attribute, this time it’s OperationBehavior.


[OperationBehavior(TransactionScopeRequired = true)]
public void Method1()
{
    //Entity Framework here
}

The method of the contract has an operation behavior that tell that it’s require to be inside a transaction scope.

The next step is to configure the web.config. It needs to have for the binding the attribute transactionflow to true.

<configuration>
  <system.serviceModel>
     <bindings>
        <wsHttpBinding>
           <binding name="MyBinding" transactionFlow="true" />
        </wsHttpBinding>
...
...

Once the binding is created, you need to use this binding.

<configuration>
 <system.serviceModel>
    <services>
      <service name="MyServiceA.Service1">
        <endpoint address="" 
                  behaviorConfiguration="behavior1" 
                  binding="wsHttpBinding"
                  bindingConfiguration="MyBinding" 
                  contract="MyServiceA.IService1" />
...
...

I have chosen wshttpbinding because to use transaction you need to use a WS-Atomic Transaction or OleTransactions protocol.

Finally, you can test the transaction by having an application that use the two services (or more) that you created with the contract that has transaction score required.

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
   try
   {
      var obj = new ServiceReference1.Service1();
      obj.Method1();
      var obj1 = new ServiceReference2.Service1();
      obj1.Method1();
      ts.Complete(); //Commit everything!
   }
   catch (Exception ex)
   {
      ts.Dispose();
   }
}

If any exception occur during the scope of the transaction, everything is rollback.

You can add additional information to the service that has method with transaction mandatory or allowed. It’s done with ServiceBehavior. You can specify the transaction time out and also the transaction isolation level. The timeout is a time that you allow for the service to be executed. The isolation level is the same as when you use transaction without services. It tells how to lock the information during the transaction. By default, it’s serializable which block everything to be changed. It’s the most protective and also the worst in term of performance. I won’t discuss about every type of isolation level but some allow you to insert new data while other allow you to simply change everything. You have to figure out which one is the correct for your needs. Do not forget to add System.Transaction reference into your project if you do want to use transaction.

[ServiceBehavior(TransactionIsolationLevel=System.Transactions.IsolationLevel.Serializable, TransactionTimeout="00:00:30")]

Entity Framework and the Unit of Work pattern

Abstract

This article is a summary of how to make the use of a unit of work with Entity Framework. First of all, Entity Framework is a unit of work by itself. You can do multiple insert, update and delete and it’s not until a SaveChanges that everything is committed to the Sql Server. The problem is that you may want to have multiple repositories. This mean that if you want to be under the same transaction that you want to share the save DbContext. Here comes the unit of work, a pattern that share the DbContext. The reference of DbContext is shared across repositories, which is interesting because if we want to be domain driven we can share the DbContext between repositories of the same domain. It’s also interesting for unit testing. The reason is that the unit of work has interface which can be easily mocked.

I have seen an article on Asp.Net website concerning Entity Framework and the unit of work pattern but I believe it’s wrong. I prefer the one of Julie Lerman in her Pluralsight video. The main reason is the one of Asp.Net includes the repository inside the unit of work and the DbContext. The one of Julie Lerman only contain the DbContext and the unit of work is passed through every repositories of the domain.

Here is the representation of every layers that we would like with the unit of work.

Layers

As you can see, the controller should contact the service layer where all queries are from databases, access to caching services and web services are executed. For the database part, we contact the data access layer accessor which is an abstraction for the unit of work and repositories. This allow every developers that use repositories to abstract the need to create the unit of work and to pass it through constructors. The accessor does have a reference to repositories and to the unit of work.

This article explains how to create a layered approach that has a controller, a service layer, a data access layer accessor with repositories and unit of work with a simple set of entities. I already have wrote an article for repository and entity framework. This was an other simpler way to design the repository. Previously, a facade was passing the DbContext to all repository, which was created the same behavior as the unit of work pattern. However, the unit of work is more elaborate and allows to unit test easily and allow you to reuse repository in several DbContext if required. Having the possibility to create several DbContext and to share it by domain (for domain driven design) is important for big software. It increase the performance of the database context by having a limited amount of entity to handle. So, the previous way to handle repository is perfect if you have under 50 entities. This is a rule of thumb and it depends of many factors. If you have a lot of entities and that you can draw specific domains, the approach of unit of work in this post is preferable. As you will see, a lot of more classes will be needed and this is not a small detail to consider before going into this way.

Creating the entities, the database context and the tables

First of all, let’s create entities and a simple context that we will call directly from the controller. This should never been done in enterprise but it will allow us to migrate the code from a simple basic code to a more heavy layered application.

public class Animal
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Animal> Enemies { get; set; }
    public virtual ICollection<Animal> EnemyOf { get; set; }
}

public class Cat : Animal
{
    public int NumberOfMustache { get; set; }
    public int RemainingLife{get;set;}
}

public class Dog : Animal
{
    public string Type { get; set; }
}

We have two classes, one is for Cat and one is for Dog. Both inherit from Animal class. These are very simple classes because we want to focus on the unit of work and not on complex classes. The next step is to create the database context.

The first step is to get Entity Framework. This can be done by using Nuget with the interface (“Manage Nuget Package”) or with a command line :

PM> install-package entityframework

Then, we need to inherit from DbContext and setup web.config to have a connection string for the database. The web.config looks like this:

<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="EntityConnectionString" connectionString="Data Source=PATRICK-I7\SQLEXPRESS;Initial Catalog=UnitOfWork;Integrated Security=SSPI;" 
         providerName="System.Data.SqlClient" />
  </connectionStrings>

The first is that we have a new configSection for Entity Framework. This has been added automatically. The line that is required to be added manually is the connection string.

The last step is to configure the entity. Since we are simplify the whole application for the purpose of the unit of work, the model class will be directly the entity. Some may want in enterprise application have an additional layer to not share entity classes with the model.

public class AllDomainContext:DbContext
{
    public AllDomainContext():base("EntityConnectionString")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //Table per type configuration
        modelBuilder.Entity<Dog>().ToTable("Animals");
        modelBuilder.Entity<Dog>().ToTable("Dogs");
        modelBuilder.Entity<Cat>().ToTable("Cats");

        //Primary keys configuration
        modelBuilder.Entity<Animal>().HasKey(k => k.Id);

        modelBuilder.Entity<Animal>()
            .HasMany(entity => entity.Enemies)
            .WithMany(d => d.EnemyOf)
            .Map(d => d.ToTable("Animals_Enemies_Association").MapLeftKey("AnimalId").MapRightKey("EnemyId"));
            
    }
}

The configuration has something special for the Enemies list because I did not wanted to handle the the association table by myself. Entity Framework can handle it for us by configure a many to many relationship with the animal class. It requires to have a table name for the many-many table with a foreign keys.

Setup the controllers, service layer and data access layer

Before even having the service layer, let’s use the context directly into the controller and see the database creation. Then, we will change to code every layers but not the unit of work yet. We can use scaffolding to leverage Visual Studio power to get code generation for us. First step, right click the controller and select add new controller.
MvcControllerWithEntityFramework

The second step is to select to model class, you can select the one of Animal and select the DbContext class. If you do not see your DbContext class (DatabaseContext), close the window and compile your application. The wizard bases its choice on the compiled resource of the project. Once generated, you can execute the code, IIS Express start by default and you just need to go to http://localhost:15635/Animal and the DbContext will start the creation of the database. If you open SQL Server Manager, the unit of work database should have 3 tables.

TabletsTPTForAnimal

Transforming to have service layers

At this stage, the architecture of the web application is not enterprise grade. The controller has a strong reference to the database context. The next step is to have everything related to the database inside a service layer which abstract entity framework. This allow us to test easily the controller without having to care about the database.

This is the current controller code at this moment.

public class AnimalController : Controller
{
    private DatabaseContext db = new DatabaseContext();

    public ActionResult Index()
    {
        return View(db.Animals.ToList());
    }

    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = db.Animals.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    public ActionResult Create()
    {
        return View();
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="Id,Name")] Animal animal)
    {
        if (ModelState.IsValid)
        {
            db.Animals.Add(animal);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(animal);
    }

    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = db.Animals.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="Id,Name")] Animal animal)
    {
        if (ModelState.IsValid)
        {
            db.Entry(animal).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(animal);
    }

    public ActionResult Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = db.Animals.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        Animal animal = db.Animals.Find(id);
        db.Animals.Remove(animal);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

If you want to test rapidly the database, just add the code in the index.

    public ActionResult Index()
    {
        var animal1 = new Animal { Name = "Boss" };
        var cat1 = new Cat { Name = "Mi" };
        var cat2 = new Cat { Name = "Do" };
        animal1.Enemies = new List<Animal> { cat1,cat2};
        db.Animals.Add(animal1);
        db.Animals.Add(cat1);
        db.Animals.Add(cat2);
        db.SaveChanges();
        return View(db.Animals.AsNoTracking().ToList());
    }

tablesDataForAssociation

The first step is to create a repository class for animal inside the DataAccessLayer folder. Normally, I create a folder called Repository to have all repositories.

public class AnimalRepository : IAnimalRepository
{
    private DatabaseContext db = new DatabaseContext();

    public Models.Animal Find(int? id)
    {
        return db.Animals.Find(id);
    }

    public void Insert(Models.Animal animal)
    {
        db.Animals.Add(animal);
        db.SaveChanges();
    }

    public void Update(Models.Animal animal)
    {
        db.Entry(animal).State = EntityState.Modified;
        db.SaveChanges();
    }

    public void Delete(Models.Animal animal)
    {
        db.Animals.Remove(animal);
        db.SaveChanges();
    }

    public void Dispose()
    {
        db.Dispose();
    }

    public IList<Animal> GetAll()
    {
        return db.Animals.AsNoTracking().ToList();
    }
}

This class as also an interface with the public method in it.

The second step is to create a service layer. Normally, we would create a new project, but to keep everything simple, let’s just add a new folder (namespace). Then, we move the DatabaseContext class from the controller to the service.

The animal service class looks like the following code.

public class AnimalService: IAnimalService
{
    private IAnimalRepository animalRepository;

    public AnimalService(IAnimalRepository animalRepository)
    {
        this.animalRepository = animalRepository;
    }

    public Models.Animal Find(int? id)
    {
        return this.animalRepository.Find(id);
    }

    public void Insert(Models.Animal animal)
    {
        this.animalRepository.Insert(animal);
    }

    public void Update(Models.Animal animal)
    {
        this.animalRepository.Update(animal);
    }

    public void Delete(Models.Animal animal)
    {
        this.animalRepository.Delete(animal);
    }
    public IList<Animal> GetAll()
    {
        return this.animalRepository.GetAll();
    }
}

It’s all the code from the controller. Later, some improvement should be done. One of this change is to move the SaveChanges because it’s not interesting to save every time we add, modify or update an entity. This cause performance problem when several entities are required to be posted to the database. However, let’s focus on the transformation first, later these details will be gone. The role of the service layer is to resemble every repository. In this situation we have only one repository. In fact, in more complex problem like in enterprise, a service has several repository and caching classes.

The next class that require changes is the animal controller class. This one now has a constructor that need an IAnimalService.

public class AnimalController : Controller
{
    private IAnimalService _service;

    public AnimalController()
    {
        _service = new AnimalService(new AnimalRepository()); 
    }

    public AnimalController(IAnimalService animalService)
    {
        _service = animalService;
    }


    public ActionResult Index()
    {
        return View(_service.GetAll());
    }

    public ActionResult Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = _service.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    public ActionResult Create()
    {
        return View();
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include="Id,Name")] Animal animal)
    {
        if (ModelState.IsValid)
        {
            _service.Insert(animal);
            return RedirectToAction("Index");
        }

        return View(animal);
    }

    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = _service.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include="Id,Name")] Animal animal)
    {
        if (ModelState.IsValid)
        {
            _service.Update(animal);
            return RedirectToAction("Index");
        }
        return View(animal);
    }

    public ActionResult Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Animal animal = _service.Find(id);
        if (animal == null)
        {
            return HttpNotFound();
        }
        return View(animal);
    }

    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int id)
    {
        Animal animal = _service.Find(id);
        _service.Delete(animal);
        return RedirectToAction("Index");
    }
}

At this stage, the controller is separated from the database by the service and the repository. Still, it’s better to not having a strong reference to AnimalService inside the controller. This is why we will extract an interface from AnimalService and we will inject the concrete class by inversion of control. This allow us to have when doing test entry point to inject a fake AnimalService that won’t goes to the database. You can use the refactoring tool to extract the interface easily.

ExtractInterface

public interface IAnimalService
{
    void Delete(Animal animal);
    Animal Find(int? id);
    IList<Animal> GetAll();
    void Insert(Animal animal);
    void Update(Animal animal);
}

Inside the controller, we have two constructors. One to help us for this example which instantiate the service layer and the real one that takes a single parameter. This is the one that you should have in your enterprise grade software because it can inject any thing of IAnimalService into the controller.

public class AnimalController : Controller
{
    private IAnimalService _service;

    public AnimalController(IAnimalService animalService)
    {
        _service = animalService;
    }
//...

Before implementing the unit of work, we will create a new repository to illustrate why the unit of work is required. We will also do a little re-factoring by changing the repository to stop having automatically a call to SaveChanges. This allow us to insert several entities in a single transaction.

This is now the animal service class and interface.

public interface IAnimalService
{
    void Delete(Animal animal);
    void Delete(IList<Animal> animals);
    Animal Find(int? id);
    IList<Animal> GetAll();
    void Save(Animal animal);
    void Save(IList<Animal> animal);
}
public class AnimalService: IAnimalService
{
    private IAnimalRepository animalRepository;

    public AnimalService(IAnimalRepository animalRepository)
    {
        this.animalRepository = animalRepository;
    }

    public Models.Animal Find(int? id)
    {
        return this.animalRepository.Find(id);
    }

    public void Delete(IList<Animal> animals)
    {
        foreach (var animal in animals)
        {
            this.animalRepository.Delete(animal);    
        }
        
        this.animalRepository.Save();
    }

    public void Delete(Models.Animal animal)
    {
        this.Delete(new List<Animal> { animal });
    }

    public IList<Animal> GetAll()
    {
        return this.animalRepository.GetAll();
    }

    public void Save(Animal animal)
    {
        Save(new List<Animal> { animal });
    }

    public void Save(IList<Animal> animals)
    {
        foreach (var animal in animals)
        {
            if (animal.Id == default(int))
            {
                this.animalRepository.Insert(animal);
            }
            else
            {
                this.animalRepository.Update(animal);
            }
        }

        this.animalRepository.Save();
    }
}

As you can see, it’s better. It also hide the complexity for update and insert by having a single method “save”. Next, we will create a new repository. We won’t code its detail but we will use it inside the AnimalService to simulate a case where we need to interact on several entities.

public class HumanRepository : IHumanRepository
{
}
public interface IHumanRepository
{
    void Insert(Models.Human humain);
}

We also need to modify the service to have in its constructor the IHumanRepository.

public class AnimalService: IAnimalService
{
    private IAnimalRepository animalRepository;
    private IHumanRepository humanRepository;

    public AnimalService(IAnimalRepository animalRepository, IHumanRepository humanRepository)
    {
        this.animalRepository = animalRepository;
        this.humanRepository = humanRepository;
    }
//...
}

Then we can simulate the need to have something in the same transaction between animal and human repository. This can be in the Save method of the AnimalService. Let’s create a new save method in the service which take an Animal and also an Human. In IAnimalService we add.

    void SaveAll(Animal animal, Human humain);

And in the concrete implementation we have :

    public void SaveAll(Animal animal, Human humain)
    {
        this.animalRepository.Insert(animal);
        this.humanRepository.Insert(humain);
    }

This is where the unit of work is required. The animal repository has its own DbContext and the human repository has its one two. Since both have not the same repository, they are in two different transaction. We could wrap these both lines with a TransactionScope but since Entity Framework is already a transaction scope and since in more complex scenario where we would want to use the DbContext furthermore, having to use the same DbContext is something viable.

Implementing Unit of Work pattern

As we have seen, we need to share the DbContext. This is where the unit of work shines. The first move is to create the unit of work which hold the DbContext.

public interface IUnitOfWork
{
    IDbSet<T> Set<T>() where T:class;

    DbEntityEntry<T> Entry<T>(T entity) where T:class;

    void SaveChanges();
}

The interface could be richer but this should be the minimal number of methods. The implementation is only having a central point for every database sets. In a more domain driven design application we could restrain entities by having a DbContext that is less general than the one created. “AllDomainContext” contains all entities set. This is perfect to create the whole database or when your application has a limited number of entities (under 50). But if you are domain driven design or with a big application, to have Entity Framework perform well and restrict the domains, having several DbContext is a good solution. With unit of work and its generic T class, you can pass any domain you want to have.

public class UnitOfWork<T>:IUnitOfWork where T : DbContext, new()
{
    public UnitOfWork()
    {
        DatabaseContext = new T();
    }

    private T DatabaseContext { get; set; }

    public void SaveChanges()
    {
        DatabaseContext.SaveChanges();
    }

    public System.Data.Entity.IDbSet<T> Set<T>() where T : class
    {
        return DatabaseContext.Set<T>();
    }

    public DbEntityEntry<T> Entry<T>(T entity) where T : class
    {
        return DatabaseContext.Entry<T>(entity);
    }
}

This unit of work is very general since it can takes T as set. This mean that any entity defined can be used. In our example, with this modified unit of work, the controller needs to be changed too.

public class AnimalController : Controller
{
    private IAnimalService _service;

    public AnimalController()
    {
        var uow = new UnitOfWork<AllDomainContext>();
        _service = new AnimalService(uow, new AnimalRepository(uow), new HumanRepository(uow)); 
    }
    public AnimalController(IAnimalService animalService)
    {
        _service = animalService;
    }
//...
}

So, the unit of work is instantiated with the domain we want. Here, it’s everything. We still have the “real” constructor that takes only the IAnimalService which is the one that should be used in the real application with inversion of control to inject the controller. Since it’s an article, to keep it simple, I show you what the IoC should do in the background.

The animal service is changed too to work with the unit of work.

public class AnimalService: IAnimalService
{
    private IAnimalRepository animalRepository;
    private IHumanRepository humanRepository;
    private IUnitOfWork unitOfWork;
    public AnimalService(IUnitOfWork unitOfWork, IAnimalRepository animalRepository, IHumanRepository humanRepository)
    {
        this.unitOfWork = unitOfWork;
        this.animalRepository = animalRepository;
        this.humanRepository = humanRepository;
    }

    public Animal Find(int? id)
    {
        return this.animalRepository.Find(id);
    }

    public void Delete(IList<Animal> animals)
    {
        foreach (var animal in animals)
        {
            this.animalRepository.Delete(animal);    
        }

        this.unitOfWork.SaveChanges();
    }

    public void Delete(Models.Animal animal)
    {
        this.Delete(new List<Animal> { animal });
    }

    public IList<Animal> GetAll()
    {
        return this.animalRepository.GetAll();
    }

    public void Save(Animal animal)
    {
        Save(new List<Animal> { animal });
    }

    public void Save(IList<Animal> animals)
    {
        foreach (var animal in animals)
        {
            if (animal.Id == default(int))
            {
                this.animalRepository.Insert(animal);
            }
            else
            {
                this.animalRepository.Update(animal);
            }
        }

        this.unitOfWork.SaveChanges();
    }

    public void SaveAll(Animal animal, Human humain)
    {
        this.animalRepository.Insert(animal);
        this.humanRepository.Insert(humain);
        this.unitOfWork.SaveChanges();
    }
}

The repository now accepts the unit of work. It can works with set defined in the domain without problem.

public class AnimalRepository : WebsiteForUnitOfWork.DataAccessLayer.Repositories.IAnimalRepository
{
    private IUnitOfWork UnitOfWork { get; set; }

    public AnimalRepository(IUnitOfWork unitOfWork)
    {
        this.UnitOfWork = unitOfWork;
    }

    public Models.Animal Find(int? id)
    {
        return UnitOfWork.Set<Animal>().Find(id);
    }

    public void Insert(Models.Animal animal)
    {
        UnitOfWork.Set<Animal>().Add(animal);
    }

    public void Update(Models.Animal animal)
    {
        UnitOfWork.Entry(animal).State = EntityState.Modified;
    }

    public void Delete(Models.Animal animal)
    {
        UnitOfWork.Set<Animal>().Remove(animal);
    }

    public IList<Animal> GetAll()
    {
        return UnitOfWork.Set<Animal>().AsNoTracking().ToList();
    }
}

It’s possible to continue to improve the unit of work and Entity Framework by going further in the use of the repository. But, what have been shown here is enterprise graded repository design. It allows you to divide the domain and improve the performance of Entity Framework by the same time. It allows to have an abstraction between the Asp.Net MVC front and the Entity Framework. It easily testable because we use interface which can be mocked easily. Benefits are clear but the price to pay is the overwhelm required to support this infrastructure. More classes need to be in place. Still, the version presented is light and once the setup is done, adding new entity is only a matter of editing the context in which it belongs and create into the repository what action is needed.

Source code

You can find the source code on GitHub for this Unit of work example.

Entity Framework Inheritance

Business logic can have model classes that inherit an other class. The data of the instanced class and the inherited class might be saved in the database when the Object Context is saved. Entity framework lets you choose the strategy you desire to save them into the database.

Three strategies are available : TPH, TPT and TPC inheritance.

Table per hierarchy (TPH) Inheritance Mapping Strategy

This is the simplest strategy. It takes all properties of the base class and all properties of the inherited class and merge them into a single table. This mean if 10 classes inherit a single class, all properties of these 10 classes plus the one of the inheritance one will be merged in 1 table.

For example you have 3 classes. Two sub-classes that inherit a single base class.

public class Book
{
    public string ISBN { get; set; }
    public int PageCount { get; set; }
}

public class Magazine : Book
{
    public string MagazineProperty { get; set; }
}

public class Encyclopedia:Book
{
    public string EncyclopediaProperty { get; set; }
}

The class diagram of these 3 classes is the following:
ClassDiagram

This will result to a single table with all property nullable for those who are from subclass.

To create a short test, simply add these three classes to a .Net project. Then, you need to setup the database context.

public class TestContext:DbContext
{
    public TestContext()
        : base("TestContext")
    {

    }
    public DbSet<Magazine> Magazines { get; set; }
    public DbSet<Encyclopedia> Encyclopedia { get; set; }
        

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<Book>().HasKey(d => d.ISBN);

    }
}

Do no forget to add Entity Framework with Nuget and setup the web.config with a good connection string. To get entity framework you can do a search inside Nuget manager or in the package console.

Menu Project>Manage NuGet Packages
Select the Online tab
Select the EntityFramework package
Click Install

or

PM> install-package entityframework

The configuration file should have a config section (which are added from Nuget) and the connection string to be setup to the Sql instance you have and the database you want to use.

<configuration>
  <configSections>
    <section name="entityFramework" 
             type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="TestContext" 
         connectionString="Data Source=PATRICK-I7\SQLEXPRESS;Initial Catalog=TestContextDatabase;Integrated Security=SSPI;" 
         providerName="System.Data.SqlClient"/>
  </connectionStrings>
...

This is the most basic setup possible, we simply set the primary key to the base class. We do not set anything for sub-classes . Then, we need to let Entity Framework create the database. For that, just instanciate the dbcontext and do something to the query. We could also generate the database with the migration tool but for simplicity, let’s just add a new Encyclopedia in the main method.

using (var context = new DataAccessLayer.TestContext())
{
    context.Encyclopedia.Add(new Models.Encyclopedia { ISBN = "123" });
    context.SaveChanges();
}

Here is how the table looks:

TableTPH

In fact, the table has an additional value which is a discriminator. This column is used by Entity Framework to know which sub class is required to be instanced. It’s possible to edit the string, but by default it’s the class name.

Discriminator

This mapping strategy is good for performance and simplicity. It’s also the default used by Entity Framework.

Table per type (TPT) Inheritance Mapping Strategy

All types are mapped to its own table. This produce a normalized database, while TPH doesn’t. For the same example as above, with TPH, the database would have 3 tables.

TPTTablets

Entity Framework performs more inner join to be able to know which table to use for subclass when information are gathered from the database. This result to be less performing than the previous approach. Nevertheless, tables are more clean because they doesn’t have a huge amount of nullable of property.

To configure table per type (TPT) it requires to set the table for the subclass.

public class TestContext : DbContext
{
    public TestContext()
        : base("TestContext")
    {
    }

    public DbSet<Book> Book { get; set; }
    public DbSet<Magazine> Magazines { get; set; }
    public DbSet<Encyclopedia> Encyclopedia { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<Magazine>().ToTable("Magazine");
        modelBuilder.Entity<Encyclopedia>().ToTable("Encyclopedia");
        modelBuilder.Entity<Book>().ToTable("Book").HasKey(d => d.ISBN);
    }
}

If we delete the database and run again the code, the database is created with two tables.

Table per concrete type (TPC) Inheritance Mapping Strategy

Tablet per concrete type, also know as TPC, create a single class per subclass. Every properties of the inherited class are set into each of the subclass table. This lead to have duplicated structure. If you have 2 classes that inherit one class, the inherited field will be in inside the two tables.

TableTPC

As you can see in the example above, the ISBN and PageCount are repeated in both of the sub classes’ table. You can also notice that they are no table for the base class. The reason is that all fields of the base are already in all sub classes.

The configuration is more complex.

public class TestContext:DbContext
{
    public TestContext()
        : base("TestContext")
    {

    }
    public DbSet<Magazine> Magazines { get; set; }
    public DbSet<Encyclopedia> Encyclopedia { get; set; }
        

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Entity<Magazine>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Magazine");
        });

        modelBuilder.Entity<Encyclopedia>().Map(m =>
        {
            m.MapInheritedProperties();
            m.ToTable("Encyclopedia");
        });
        modelBuilder.Entity<Magazine>().HasKey(d => d.ISBN);
        modelBuilder.Entity<Encyclopedia>().HasKey(d => d.ISBN);
    }
}

The code generated in SQL is complex. It has sub query with union to know from which table to take its data. This result to have bad performance for heavy inheritance model. TPC is good for deep inheritance, TPH is good for small entity with not a lot of property and TPT is good for small inheritance level with many properties. Personally, I lean for TPT most of the time. Having a normalize database is important in most enterprise and performance is not that bad if the inheritance is only one level.

Asp.Net MVC5 with localization resource

This post contains information to localize your Asp.Net MVC web application. I have already covered how to change the language from the url without having to use the culture code in the url. This post goal is to detect the default language of the user browser for a default language and to let the user select his preferred language. Never only depend of the browser language for choosing localization. I have a French keyboard since I am living in Quebec, Canada and I hate to see French localized website. I want to see everything in English. I am not the only one that desire to see specific website in specific language and this is why you should also let the user choose in which language to display your string, date and number.

Localization works by setting the current thread Culture and Culture UI with a CultureInfo class. CultureInfo can contains the region or not. So, you can have the language and the country or just the language.

var culture1 = new System.Globalization.CultureInfo("fr");
var culture2 = new System.Globalization.CultureInfo("fr-CA");

In the example above, culture1 specify the language, French, but doesn’t specify the region which can be a problem for number and date. This is why it’s always better to be region specific instead of using neutral culture. With experience, you will see that your customer won’t want the European format for currency if they live in North America (euro is not Canadian dollar!).

In a MVC application, the language is often set in the user session or cookie. It’s then loaded back when one of your controller is called. Normally, all your controllers should inherit from a base controller. This is the perfect place to set the thread culture back from the session or cookie.

You can set the thread inside the OnActionExecuting.

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
      Thread.CurrentThread.CurrentUICulture = new CultureInfo(CurrentUser.Language);
      Thread.CurrentThread.CurrentCulture = new CultureInfo(CurrentUser.Language);
      //...
}

If you want to use by default if the session is not set the language set in the browser, it’s possible. This language is set in the preference of the browser. Here is two screenshots that explain how to adjust the language for Chrome and for Internet Explorer.

acceptedLanguage

acceptedLanguageIE

This set the Accept-Language in the http header. The server receive this information, and you can read it from the Http Request header.

cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages.First();

If the language is not available inside your resource file, it falls back the the localized file that doesn’t have any culture. Normally, you have resource files like Message.resx, Message.en.resx, Message.fr.resx. As you can see, we do not specify the region, but we could. In fact, Asp.Net try to take the more specific to the less specific. This is very useful because you can translate very specific string for a specific region in Message.fr-Ca.resx without having to define every others strings. When creating your resource files, set the access modifier to Public. This will allow to use your resource outside the project, which is good if you have a project for resource. This set the build option from ResXFileCodeGenerator to PublicResXFileCodeGenerator for the custom tool to use. From here, you can use the resource inside your application by specifying the namespace and the name of the resource (without any culture) and with the key name of the resource.

<h1>
   @ResourcesNamespace.Titles.CreateCustomer
</h1>

If you do not want to type the namespace every time you can set a using at the top of the file and for views you can also specify in the web.config the namespace to be added by default. Often, this is added into the web.config of the Views folder and not the whole application since in the majority of time, you have resources for each Views folder. If you wan to add the namespace into the default ones, add your namespace under razor configuration.

<configuration>
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization"/>
        <add namespace="System.Web.Routing" />
        <add namespace="YourNamespaceHere" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

Finally, if you want to use the default language then the session, here is the code you need to use inside your controller. Keep it minds that this is not what should be done if you are using what I have previously written concerning url language. This is because, the url keep the language and you do not need to check the accepted language of the browser, neither the session.

protected ICurrentUser CurrentUser
{
	get
	{
		UserSessionDTO currentUser = _sessionHandler.GetUser();
		if (currentUser != null)
		{
			UserProfile userProfile = _mapperFactory.UserSessionDTO.GetModel(currentUser);
			return userProfile;
		}
		else
		{
			ICurrentUser currentUserFromProvider = _userProvider.Account;
			UserProfile fullUserProfile = _serviceFactory.Account.GetByUserName(currentUserFromProvider.UserName);
			if (fullUserProfile == null)//Case of a non identified user
			{
				fullUserProfile = new UserProfile();
				fullUserProfile.Language =  Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages.First():"en-US";
			}
			return fullUserProfile;
		}
	}
}

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
	Thread.CurrentThread.CurrentUICulture = new CultureInfo(CurrentUser.Language);
	Thread.CurrentThread.CurrentCulture = new CultureInfo(CurrentUser.Language);
	base.OnActionExecuting(filterContext);
	//....
}

The code above is a little bit more than necessary. It has in the base controller something that check if the user is already logged in the session. If yes, it returns the object fully loaded. If not, which is the case for a new user that come on your website, it uses the temporary user from the user and verify it has a User Profile which should be null. This create a temporary User Profile and set the language which is in fact the culture (I should rename this property). From the Controller.Request which is of type System.Web.HttpRequestBase, you can read the UserLanguage and take the first one defined. If none is set, I choose English from United States Of America.

Asp.Net MVC localized url without having to specify the language in it

Often we see people using for multi language website the possibility to change the language by adding a property into the session of the user which tell the server to change the culture and culture ui to something else than english. This is fine because resources files handle multi languages if the culture is set correctly. An other way to do it, is to allow the user to have the culture into the url like the following example : http://yourwebsite.com/fr-ca/controllerName/actionName. I personally dislike this approach. It has the advantage to give the possibility to send an url to someone and to have it in the correct language, this can’t be done with the previous solution of allowing the user to change the language and set it to the session. But, it has the disadvantage to tell that the language is French and still having the text in the url in English. The solution is suggest is that if you have public page that these one should control the language with an url that is already in the desired language. You should also let the user select the language and set the client language into a session which will tell the server how to display the url. This solution gives you good SEO url with named url in the good language and allow the user to control the language if this one want to change it.

At the end, what we want is to have url like this : http://yourwebsite.com/Compte/Identification for French website and for English : http://yourwebsite.com/Account/Login

Everything start by changing the routing. This can be done by opening the file RouteConfig.cs that is inside your web project under the folder App_Start.

Several things need to be done. First, we need to specify which culture will be used by you application. Then, you will have to use a custom structure to specify every controllers and actions with the translated values. This is required to associate every language word to an existing controller and existing action. Finally, the last step is to create a binder that will allow you to use the new mechanism to translate route. This is an example of how the routeConfig.cs looks for a brand new Asp.Net MVC5 application with the Home and Account controller translated.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        var cultureEN = CultureInfo.GetCultureInfo("en-US");
        var cultureFR = CultureInfo.GetCultureInfo("fr-FR");

        var translationTables = new List<ControllerTranslation>{ 
            new ControllerTranslation("Home"
                    , new List<Translation>{
                                new Translation(cultureEN, "Home")
                            ,new Translation(cultureFR, "Demarrer")
                    }
                ,new List<ActionTranslation>{
                        new ActionTranslation("About"
                        , new List<Translation>{
                                new Translation(cultureEN, "About")
                            ,new Translation(cultureFR, "Infos")
                        })
                        , new ActionTranslation("Home"
                        , new List<Translation>{
                                new Translation(cultureEN, "Home")
                            ,new Translation(cultureFR, "Demarrer")
                        })
                    , new ActionTranslation("Contact"
                        , new List<Translation>{
                                new Translation(cultureEN, "Contact")
                            ,new Translation(cultureFR, "InformationSurLaPersonne")
                        })
                })
            ,new ControllerTranslation("Account"
                    ,
                    new List<Translation>{
                                new Translation(cultureEN, "Account")
                            ,new Translation(cultureFR, "Compte")
                    }
                    ,
                    new List<ActionTranslation>
                    {
                        new ActionTranslation("Login"
                        , new List<Translation>{
                                new Translation(cultureEN, "Login")
                            ,new Translation(cultureFR, "Authentification")
                        })
                        , 
                        new ActionTranslation("Register"
                        , new List<Translation>{
                                new Translation(cultureEN, "Register")
                            ,new Translation(cultureFR, "Enregistrement")
                        })

                    }
            )
        };

        routes.Add("LocalizedRoute", new TranslatedRoute(
            "{controller}/{action}/{id}",
            new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
            translationTables,
            new MvcRouteHandler()));

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

As you can see, it can be very exhaustive to define every actions of every controller. However, this configuration can be saved in a database and loaded once for the application if you desire.

We are using a lot of classes that you will need. First of all, let’s define all classes that are used to structure the controllers and actions translation. I have separated all classes in 4 files.

RoutingClasses

public class ControllerTranslation
{
    public string ControllerName { get; set; }
    public List<Translation> Translation { get; set; }
    public List<ActionTranslation> ActionTranslations { get; set; }

    public ControllerTranslation(string controllerName, List<Translation> translation, List<ActionTranslation> actionsList)
    {
        this.ControllerName = controllerName;
        this.Translation = translation;
        this.ActionTranslations = actionsList;
    }
}

This is the main class that has the controller name, which is required to be able to bind the translated name for the real code name. It contains a translation list which contains for every cultures the new name which is used in the url. Then, it contains a list of actions. This way, we have a well structured a logically separated structure.

public class ActionTranslation
{
    public string ActionName { get; set; }
    public List<Translation> Translation { get; set; }

    public ActionTranslation(string actionName, List<Translation> translation)
    {
        this.ActionName = actionName;
        this.Translation = translation;
    }
}

ActionTranslation is almost the same as ControllerTranslation. The only difference it that it doesn’t contain a list of class.

public class Translation
{
    public CultureInfo CultureInfo { get; set; }
    public string TranslatedValue { get; set; }
    public Translation(CultureInfo culture, string translatedValue)
    {
        CultureInfo = culture;
        TranslatedValue = translatedValue;
    }
}

Finally, the Translation class contain a culture information that is associated to a string that is translated in the language of the culture.

Take note that you could also have a AreaTranslation that would have a Controller class list. This example is extensible for more level of url structure without problem. For the simplicity, this article concentrate its effort for Controller and Action only.

The last class is here to define a new Route. In the RouteConfig.cs class, the route is defined, before the default route.

 routes.Add("LocalizedRoute", new TranslatedRoute(
               "{controller}/{action}/{id}",
               new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }),
               translationTables,
               new MvcRouteHandler()));

The third parameter takes the controller list that has all actions translated. A route is a class that inherit from System.Web.Routing.Route class. This class allow you to override two important methods. RouteData GetRouteData(HttpContextBase httpContext) and VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values). The first one is used when a request is done to the server. This mean that is takes the localized words of the controller and action of the URL and translated them with your list of controller defined previously in the RouteConfig.cs. The second one is used by Html helper to create new link. This mean it takes the real controller and action name and translated them to create localized link for your application. This is awesome because not only your url are in the good language but also all your link everywhere in your application is automatically translated.

public class TranslatedRoute : Route
{

    public List<ControllerTranslation> Controllers { get; private set; }

    public TranslatedRoute(string url, RouteValueDictionary defaults, List<ControllerTranslation> controllers, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler)
    {
        this.Controllers = controllers;
    }

    public TranslatedRoute(string url, RouteValueDictionary defaults, List<ControllerTranslation> controllers, RouteValueDictionary constraints, IRouteHandler routeHandler)
        : base(url, defaults, constraints, routeHandler)
    {
        this.Controllers = controllers;
    }

    /// <summary>
    /// Translate URL to route
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData routeData = base.GetRouteData(httpContext);
        if (routeData == null) return null;

        string controllerFromUrl = routeData.Values["controller"].ToString();
        string actionFromUrl = routeData.Values["action"].ToString();
        var controllerTranslation = this.Controllers.FirstOrDefault(d => d.Translation.Any(rf=>rf.TranslatedValue == controllerFromUrl));
        var controllerCulture = this.Controllers.SelectMany(d => d.Translation).FirstOrDefault(f => f.TranslatedValue == controllerFromUrl).CultureInfo;
        if (controllerTranslation != null)
        {
            routeData.Values["controller"] = controllerTranslation.ControllerName;
            var actionTranslation = controllerTranslation.ActionTranslations.FirstOrDefault(d => d.Translation.Any(rf => rf.TranslatedValue == actionFromUrl));
            if (actionTranslation != null)
            {
                  
                routeData.Values["action"] = actionTranslation.ActionName;
                    
            }
            System.Threading.Thread.CurrentThread.CurrentCulture = controllerCulture;
            System.Threading.Thread.CurrentThread.CurrentUICulture = controllerCulture;
        }
            

        return routeData;
    }

    /// <summary>
    /// Used in Html helper to create link
    /// </summary>
    /// <param name="requestContext"></param>
    /// <param name="values"></param>
    /// <returns></returns>
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {

        var requestedController = values["controller"];
        var requestedAction = values["action"];
        var controllerTranslation = this.Controllers.FirstOrDefault(d => d.Translation.Any(rf => rf.TranslatedValue == requestedController));
        var actionTranslation = controllerTranslation.ActionTranslations.FirstOrDefault(d => d.Translation.Any(rf => rf.TranslatedValue == requestedAction));
        var controllerTranslatedName = controllerTranslation.Translation.FirstOrDefault(d => d.CultureInfo == System.Threading.Thread.CurrentThread.CurrentCulture).TranslatedValue;
        if (controllerTranslatedName != null)
            values["controller"] = controllerTranslatedName;
        var actionTranslate = controllerTranslation.ActionTranslations.FirstOrDefault(d => d.Translation.Any(rf => rf.TranslatedValue == requestedAction));
        if (actionTranslate != null)
        {
            var actionTranslateName = actionTranslate.Translation.FirstOrDefault(d => d.CultureInfo == System.Threading.Thread.CurrentThread.CurrentCulture).TranslatedValue;
            if (actionTranslateName != null)
                values["action"] = actionTranslateName;
        }
        return base.GetVirtualPath(requestContext, values);
    }
}

For both method, if we do not find the controller name or action name, it falls back to the default name. This way, nothing crash. I have also added two lines that change the thread language. This is not require if you do not want to change the language of the whole application but it seems logical to do it. If you send an url in French, you certainly want to have the whole page to use French resources.

TranslatedUrlAndLinks

You can have the complete source code on GitHub.