Quick Tutorial

The goal of this tutorial is to see the basics steps of creating an application using Arch.

Think about your Model

The first thing you have to do is to think about your model. You can be in model first or Database first but you have to think first about you model.

Create a project dedicated to your mapping you can name it "ProjectName.Mapping"
If you are using Entity Framework you can create an Edmx, import your model from an existing database (and correct property/entity/relation names!) or create your model and generate your database (or manually map your database)


Now I can create my model. First I create a project for my model and name it "ProjectName.Model"
Arch# is compatible with POCO, so you can use POCO, but entity object and self tracking entities too.
EF Support POCO, so we will start with a POCO base model.
My personal opinion is that if I use POCO, it's not for having clean source code by for doing everything I want on the entities.
So I'll have to switch from EF generated code to classic writable C# classes.

To achieve this, I am doing this way:
  • I add a code generation item to the edmx, the DbContext create pretty good (simple and clean) poco.
  • I name the T4 file GeneratedModel.tt .
  • Once created I remove the GeneratedModel.Context.tt . Arch# doesn't need a specific Context.
  • I go to the properties panel of all the generated classes and set the "Build Action" to "None" (these classes are here only as a standard EF model for reading)
  • Go to the explorer in the Mapping project and drag and drop the entities files to the Model project.
  • Change the namespace of your entities to "ProjectName.Model".

Ok we are done. Now we have a simple POCO model. Now we can create a rich Model in the "spirit of Arch#".

My approach is to make richer the entities with:
  • Reference "Arch.Model"
  • Inherit of Entity<TId> (think about removing your Id property)
  • Add Arch# aspects
  • Add Data annotations
  • Add Business methods

Data access

Now we can create a data access layer. Arch# philosophie is to use a generic Repository Layer
Create 2 projects:
  • "ProjectName.Data" that will contains the base generic Repository and entity specific repositories
  • "ProjectName.Data.Contracts" that contains specific repositories interfaces

Create your base repository in the Data project name it "Repository" (the name is mandatory !) and inherite of one of the repository proposed by Arch# or created by yourself.

Example with EF 4.1 repository:

namespace Arch.Samples.Data
{
    public class Repository<T> : DbRepository<T> where T : class, new()
    {
    }
}

And that all ... Yes it's sufficient!

Now you can create specific Repository. For exemple imagine that when you get an user, you have to load data from an active directory. You have to create an UserRepository and override the "Load" method.

namespace Arch.Samples.Data
{
    public class UserRepository<User> : Repository<User>
    {
        public override User Load(object id)
        {
            var entity = base.Load(id);
            //get data from repository here
            return entity;
        }
    }
}

So why the Data.Contract project is empty? It's empty because you don't have specific access that the IRepository support.
Imagine you need a "Full text search" on a Todo application. You have to first create a specific interface for your repository in the Data.Contracts project:

namespace Arch.Samples.Data.Contracts
{
    public interface ITodoRepository : IRepository<Todo>
    {
        IEnumerable<Todo> Search(string text);
    }
}

Now you can create a Todo repository like this with a linq query (or if you prefer a stored procedure,Full text search...) :

namespace Arch.Samples.Data
{
    public class TodoRepository : Repository<Todo>, ITodoRepository
    {
        public IEnumerable<Todo> Search(string text)
        {
            return Find(t => t.Title.Contains(text) || t.Description.Contains(text));
        }
    }
}

Inversion of Control

Arch# is designed to be used with Inversion of control with Microsoft Unity, the main class is the "DependencyContainer" class.
This class has to access to the layers of your application. For example in an asp.Net MVC application, this class can be in your Web project.
The minimal configuration you have to do is the creation of your data access layer and map your Repository class in the "RegisterTypes" method.

Example for an MVC application using EF4.1 :

namespace Arch.Samples.Mvc.Infrastructure
{
    public class DependencyContainer : ServerDependencyContainer
    {
        public override void RegisterTypes(IUnityContainer container)
        {
            container
                .RegisterType(typeof (IRepository<>), typeof (Repository<>))
                .RegisterType<DbContext, DbContext>(
                    new PerRequestLifetimeManager<DbContext>(),
                    new InjectionFactory(
                        c =>
                            {
                                var context = new DbContext("name=Arch");
                                context.Configuration.ProxyCreationEnabled = true;
                                context.Configuration.LazyLoadingEnabled = true;
                                return context;
                            }))
                ;
        }
    }
}

The Inversion of control configuration is done. Now you can use it in your application.
There are multiple way to user Inversion of Control, the best aproach is to create your top levels classes with the container.
For exemple in an Asp.Net MVC application the top level classes are the controllers, to add the IoC concept in the controllers you have to create a new controller factory like this:

namespace Arch.Web.IoC
{
    public class ControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (controllerType != null)
                return (IController)ArchDependencyContainer.Container.Resolve(controllerType);
            return base.GetControllerInstance(requestContext, controllerType);
        }
    }
}

This class is include in Arch#, you can use it if it respond to your needs.
Now you ve got to instanciate you DependencyContainer and your controller factory in the Application_Start of your Global.asax file like this:

namespace Arch.Samples.Mvc
{
    public class MvcApplication : System.Web.HttpApplication
    {
//[...]
        protected void Application_Start()
        {
            new UnityContainer().InitDependencyContainer<DependencyContainer>();
            ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
            //[...]
        }
    }
}

Now you can inject dependencies like this in your controllers:

namespace Arch.Samples.Mvc.Controllers
{
    public class TodoController : Controller
    {
        [Dependency]
        public IRepository<Todo> TodoRepository { get; set; }
    }
}

A Repository will be instanciated automaticaly.


To be continued ...

Last edited Mar 31, 2011 at 9:51 PM by anthyme, version 7

Comments

No comments yet.