Vlad's blog

In programming veritas

Posts Tagged ‘Task Manager

Task Manager: dependency injection

leave a comment »

This is the fourth post of a series of posts on developing Web applications using ASP.Net MVC. The previous two posts are available here:

The source code is available on CodePlex.

In any application, there is the problem of managing dependencies between components. There is no single solution here. In many cases, there is nothing wrong when a client explicitly creates instances of the required services. In our case we need to look at the dependencies between the application layers. The following diagram shows that the Presentation layer depends on the Domain layer and Data Access layer, and Domain layer depends on the Data Access layer.

Indeed, ProjectController, TaskController and AccountController require a reference to the repository to perform CRUD operations. Some operations require a reference to IProjectDeleteService or IUserDeleteService or IUserActionLogger. Implementations of services also require a reference to the repository. Technically, all three layers are represented by three different assemblies. All interfaces are declared as public, while the implementation declared as internal.
One possible solution here is to use a DI container. There are a sufficient number of libraries that provide functionality of DI container, so the best choice is often determined by personal preference. Personally I like Autofac. The idea of ​​modules is useful for isolation of layers. Thus, each layer will be represented by own module, which registers the dependencies. For example, DomainLayer registers services that are provided by Domain layer.

public class DomainLayer : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<UserActionLogger>().As<IUserActionLogger>().InstancePerLifetimeScope();
        builder.RegisterType<ProjectDeleteService>().As<IProjectDeleteService>().InstancePerLifetimeScope();
        builder.RegisterType<TaskUpdateService>().As<ITaskUpdateService>().InstancePerLifetimeScope();
    }
}

Instances of modules are created to initialize DI container at the application startup.

protected void Application_Start()
{
    var builder = new ContainerBuilder();

    builder.RegisterModule(new DataAccessLayer());
    builder.RegisterModule(new DomainLayer());
    builder.RegisterModule(new PresentationLayer());

    IContainer container = builder.Build();

    // Setup DI as default MVC controller factory
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

Another task that can be solved by DI container is to manage the lifetime of objects. For example, in order to create instance of ProjectController you need the following services.

  • ProjectRepository
  • UserActionLogger
  • TaskManagerDbContext
  • ProjectDeleteService

ProjectRepository also depends on TaskManagerDbContext. We need to make sure we have only one instance of TaskManagerDbContext in current HTTP request. Otherwise every service will get own copy of TaskManagerDbContext.

When a request is made for a service, Autofac can return a single instance within some kind of context, e.g. a thread or an HTTP request. To do this, call InstancePerLifetimeScope() method when registering the dependency.

public class DataAccessLayer : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        Database.SetInitializer(new DatabaseInitializer()); // Initialize database
           
        builder.RegisterType<TaskRepository>().As<ITaskRepository>().InstancePerLifetimeScope();
        builder.RegisterType<ProjectRepository>().As<IProjectRepository>().InstancePerLifetimeScope();
        builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerLifetimeScope();
        builder.RegisterType<ProjectLogWriter>().As<IProjectLogWriter>().InstancePerLifetimeScope();
        builder.RegisterType<TaskLogWriter>().As<ITaskLogWriter>().InstancePerLifetimeScope();

        builder.RegisterType<TaskManagerDbContext>()
            .As<IUnitOfWork>()
            .As<TaskManagerDbContext>()
            .InstancePerLifetimeScope();
    }
}

Autofac is smart enough to undestand Lazy class which is usually used for lazy initialization. For example, IProjectDeleteService needed to create ProjectController, but in reality it is only required when processing a request to delete a project. In this case it is convenient to use lazy initialization.

public ProjectController(IProjectRepository projectRepository, 
Lazy<IProjectDeleteService> projectDeleteService, 
IUnitOfWork unitOfWork, 
IUserActionLogger userActionLogger, TabContainer tabContainer)
{
    Contract.Requires(projectRepository != null);
    Contract.Requires(unitOfWork != null);

    _projectRepository = projectRepository;
    _tabContainer = tabContainer;
    _projectDeleteService = projectDeleteService;
    _unitOfWork = unitOfWork;
    _userActionLogger = userActionLogger;

    if(log.IsDebugEnabled) log.Debug("Created ProjectController");
}

Generally, Autofac supports a well defined system of relationship types. More information about the features can be found in blog of one of the developers.

Written by vsukhachev

January 8, 2012 at 1:34 pm

Posted in Development

Tagged with ,

Task Manager: data access layer

leave a comment »

This is the third post of a series of posts on developing Web applications using ASP.Net MVC. The previous two posts are available here:

The source code is available on CodePlex.

The data access layer allows application components to abstract from implementation details of a specific database access technology. Since we use ORM, we already have a substantial level of abstraction that is implemented in the ORM, in our case, Entity Framework. In the case of a simple application like Task Manager, perhaps, there is no need for a separate level of abstraction to isolate parts of the EF from other system components. The only advantage here is that we can easily migrate to another ORM, such as NHibernate. On the other hand, it does not require much effort and demonstrates the good approach in terms of application architecture.
In this case, the standard solution is to use a pattern Repository in conjunction with Unit of work .
From a design standpoint it is important to decide which entity requires a separate repository, and what is not. Eric Evans in his book about DDD recommends creating a repository for each aggregate root. In our case we have three aggregate roots: Project, Task, User, respectively, we have three repositories:

  • IProjectRepository
  • ITaskRepository
  • IUserRepository

Since all the repositories have a standard set of CRUD operations, plus methods for searching and filtering, we can define the common interface they must implement.

public interface IRepository<TEntity, TKey>
    where TEntity: IEntity<TKey>
{
    IQueryable<TEntity> All { get; }
    IQueryable<TEntity> AllIncluding(params Expression<Func<TEntity, object>>[] includeProperties);
    TEntity Find(TKey id);
    void Insert(TEntity entity);
    void Update(TEntity entity);
    void Delete(TKey id);
}

All methods should be obvious, except, perhaps, AllIncluding, but I will tell about it later.
Generic interface IRepository has two parameters: TEntity – that defines the serialized class and TKey – type of the primary key (usually int). TEntity must implement the interface IEntity, which defines the Id property to store the primary key values.

public interface IEntity<T>
{
    T Id { get; set; }
}

Pattern Unit of work is implemented using the interface IUnitOfWork, which is available to clients along with a specific repository.

public interface IUnitOfWork
{
    void Save();
}

Read the rest of this entry »

Written by vsukhachev

January 3, 2012 at 7:01 pm

Posted in Development

Tagged with ,

Task Manager: application architecture and domain model

with 5 comments

This is the second post of a series of posts on developing Web applications using ASP.Net MVC. The previous post is available here. The source code is available on CodePlex.

Application architecture

The system has the following layers:

  • Presentation layer
  • Domain layer
  • Data Access layer
  • ORM
  • Database layer

The last two layers (ORM and Database) are more likely to complete the picture, because they have already been implemented by the Entity Framework.


Read the rest of this entry »

Written by vsukhachev

December 29, 2011 at 11:17 am

Posted in Development, Uncategorized

Tagged with ,

Task Manager

leave a comment »

The best way to learn a new framework is to build something with it. I am going to write a series of posts on how to develop Web applications using ASP.Net MVC, and a number of related technologies and libraries:

  • Entity Framework Code First
  • Autofac
  • Automapper
  • Rhino Mocks

The source code is available on CodePlex. The following posts are available at the moment.

In addition to questions related to the use of mentioned technologies will be discussed principles of DDD in designing application architecture, as well as writing unit tests for components of the system.
Task Manager is a small, but a complete application for managing tasks and projects. The user can create a new project or add tasks in the current project.

In order to create new task you must select project from the list of available projects and choose an assignee.

Each user can view a list of your active tasks, as well as a list of all tasks and a list of completed tasks.

Every task has a log.

Users can add their comments to the task.

Written by vsukhachev

December 28, 2011 at 8:18 am

Posted in Development

Tagged with ,