Entity framework 4 – CTP3 – Code first vs Linq to Sql

I just started doing some architectural changes to my old code in my previous article for Entity framework 4 (EF4) and at the same time updating it to use the new CTP3 add-on as well as writing the same code for Linq to Sql (L2Sql). I didn’t find any incompatibilities when updating from CTP2 to CTP3 but I did find something annoying. The Entity framework team is aware of this bug and will try to resolve this issue in the future.

This article shows you a solution where you DON’T use a designer or wizard for designing your model, it focuses on “Code first” where the entities are designed manually in code, as pure POCOs.

1 – The design

The design of my solution for dealing with storage of entities, has the following main components: Mappings-resolver, Storage-provider and Unit-of-work. A part from these there’s an ObjectContext and an ObjectContextBuilder, which you don’t have to deal with explicitly, since they are consumed by the Storage-provider and the Unit-of-work. The interface definition of a Storage-provider and the Unit-o-work, looks like this:


Interface for Storage-provider & Unit-of-work

1.1 – Mappings-resolver

The Mappings-resolver is responsible for finding the types that are to be handled by the Storage-provider; in other words, it locates your entities which are provided to the ObjectContextBuilder so that it can register mapping-information for each found entity and later on pass this information on to each created ObjectContext. For L2Sql, the mappings are described using attributes in the entity itself and the mappings are contained in an AttributeMappingSource. For EF4, the mappings are described using the fluent-API of the EntityConfiguration<T> class (more examples of this in the code section below).


L2Sql – Mappings-resolver


EF4 – Mappings-resolver

Both L2Sql and EF4 has two different Mapping-resolver implementations. One that scans for types in a specified assembly, and one that scans for types in the assembly that contains the interface that is provided via generics. With the second approach, the types also need to implement this interface, hence it acts as a filter, indicating if a type should be included or not. No matter which mappings-resolver you choose, all types needs to be a non-abstract class.

1.1.1 – L2SqlMappingsResolver

The L2Sql implementation looks for types that are classes that isn’t abstract and that are decorated with the attribute: TableAttribute. Each found type is then registered with the MappingSource’s model.

1.1.2 – EFMappingsResolver

The EF implementation looks for types that are classes that: isn’t abstract; extends EntityConfiguration<T>;where the name ends with Mapping.

1.2 – Storage-provider

The Storage-provider is designed to be long lived whilst the Unit-of-work is designed to be short-lived. The Storage-provider is tied to a certain implementation like: EF4 or L2Sql. It’s main responsibility is to create new instances of Unit-of-works, which then is used to-do CRUD-operations against the data source specified in the connection string passed to the Storage-provider. If you are familiar with NHibernate, you can look at the storage-provider as the Session factory.

1.3 – Unit-of-work

The Unit-of-work is designed to be short lived. It wraps the ObjectContext and provides a common API independent of the actual implementation (EF4 or L2Sql). It implements IDisposable so that you can use it in conjunction with an using-block. You use it to perform inserts, updates and deletes as well as for querying your model. When performing insert, updates and deletes, you have to flush your changes. You can see the Flush-operation as a sort of commit. Note! It’s not using transactions. If you want to use database transactions, you can i.e use the TransactionScope, or extend the Storage-provider to have a member: CreateUnitOfWorkWithTransaction() : ITransactionalUnitOfWork; or something like that.

L2Sql & EF4, Storage-provider and Unit-of-work

1.4 – ObjectContextBuilder & ObjectContext

The ObjectContextBuilder is responsible for holding mappings (added by passing a mappings-resolver to RegisterMappings) and for creating new instances of ObjectContexts, which are injected to the UnitOfWork instances.

1.4.1 – L2SqlObjectContext

As of right now this class just extends the DataContext class. It’s there to bring some consistency in the namings of all the components involved in the L2Sql-implementation. It might get extended in the future, but for now, it’s only implemented to bring consistency, so that L2SqlObjectContextBuilder and L2SqlUnitOfWork can work with L2SqlObjectContext rather than DataContext.

1.4.2 – EfObjectContextBuilder & ObjectContext

The EF4-implementation of ObjectContextBuilder, it extends the allready existing ContextBuilder. Also note that the EF4 ObjectContextBuilder holds a couple of alternative ways to register mappings, but as long as you use the Storage-provider, you don’t have to care about these. But if you want to extend something or use the builder directly, these members are there to let you add mappings.


L2Sql & EF4 – ObjectContextBuilder & ObjectContext

2 – How to consume the lib

That was a very brief and abstract explanation of the parts involved, now lets take a look at how to consume the lib.

2.1 – L2Sql

Step 1 – Define the model & the mappings

The entity can be placed freely in your assembly and doesn’t have to be generated by the DBML-designer. The example we are dealing with a very simple Customer class. Although I can specify mappings with XML in L2Sql, I tend to like the attribute-decoration approach more easygoing and clear, since I don’t have to locate a certain xml-file for managing the mappings.

[Serializable]
[Table(Name = "Customers")]
public class Customer
{
    [Column(Name = "CustomerId", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int Id { get; set; }

    [Column(IsVersion = true, IsDbGenerated = true, CanBeNull = false, AutoSync = AutoSync.Always)]
    public byte[] Version { get; set; }

    [Column(CanBeNull = true, DbType = "NVARCHAR(100)")]
    public string Firstname { get; set; }

    [Column(CanBeNull = true, DbType = "NVARCHAR(100)")]
    public string Lastname { get; set; }

    public string Name
    {
        get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); }
    }
}

Nothing spectacular. I have chosen to have an Id-field that is set-up as an identity as well as a Version-field for concurrency detection.

Step 2 – Extract the mappings

The ObjectContextBuilder needs to know where the data source is as well as what mappings to be used, hence we need to provide a connection string as well as a MappingsResolver.

Alternative 1

var mappingsResolver = new L2SqlMappingsResolverByAssemblyScan(assemblyWithEntities);

In the code above, I have chosen to go with a resolver that extracts the mappings from an assembly that contains my Linq-entities and the attribute-mappings (the Customer).

If I would like to I could let all my entities implement a certain interface and use it to extract the entities. The resolver will then look at the assembly containing the interface, and will look for the classes that implements this interface. To use this solution, I just need to use another resolver:

Alternative 2

var mappingsResolver = new L2SqlMappingsResolverByInterfaceFilterType<IEntity>();
Step 3 – Create a Storage-provider

After having defined my mappings and selected a strategy for fetching them (Step 1 & 2), I can now create my long-lived Storage-provider. Just give it a valid connection string for a Ms-Sql database and the mappings-resolver.

var storageProvider = new L2SqlStorageProvider(connectionString, mappingsResolver);

The rest of the Steps are common between the L2Sql and EF4 implementation, so before proceeding with Step 4, lets look at the EF4-implementation of Step 1 – 3.

2.2 – EF4

Step 1 – Define the model & the mappings

With the EF4 solution, the class doesn’t contain the attributes, instead the mappings are configured in a separate class, using the fluent-API of the EntityConfiguration-class.

public interface IEntity
{
    int Id { get; set; }
    byte[] Version { get; set; }
}

[Serializable]
public class Customer
    : IEntity
{
    public int Id { get; set; }

    public byte[] Version { get; set; }

    public string Firstname { get; set; }

    public string Lastname { get; set; }

    public string Name
    {
        get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); }
    }
}

I have chosen to let my entities implement a certain interface so that I can re-use some mappingconfiguration by having a base-class for my mappings (EntityMapping<T>)

[Serializable]
public class EntityMapping<T> : EntityConfiguration<EfCustomer>
    where T : IEntity
{
    protected EntityMapping()
    {
        HasKey(o => o.Id);
        Property(o => o.Id)
            .IsIdentity();
        Property(o => o.Version)
            .IsConcurrencyToken()
            .IsRequired()
            .HasStoreType("timestamp")
            .StoreGeneratedPattern = StoreGeneratedPattern.Computed;   
    }
}

[Serializable]
public class CustomerMapping
    : EntityMapping<EfCustomer>
{
    public CustomerMapping()
    {
        Property(o => o.Firstname)
            .HasMaxLength(100)
            .IsUnicode()
            .IsOptional();
        Property(o => o.Lastname)
            .HasMaxLength(100)
            .IsUnicode()
            .IsOptional();
    }
}
Step 2 – Extract the mappings

When dealing with the EF4-solution the types to be extracted by the MappingsResolver isn’t the entities but instead the Mapping-classes. This is done using one of two alternatives:

Alternative 1

var mappingsResolver = new EfMappingsResolverByAssemblyScan(assemblyWithEntities);

Alternative 2

var mappingsResolver = new EfMappingsResolverByInterfaceFilterType<IEntityMapping>();

In the Alternative 2 the IEntityMapping could be an empty interface definition that is implemented by the mapping-classes.

Step 3 – Create a Storage-provider

After having defined my mappings and selected a strategy for fetching them (Step 1 & 2), I can now create my long-lived Storage-provider. Just give it a valid connection string, a providername (System.Data.SqlClient used by the DbProviderFactory) and the mappings resolver.

var storageProvider = new EfStorageProvider(connectionString, providerName, mappingsResolver);

That’s it. Now we have gone through all the implementation-specific scenarios. The rest of the steps are common between the L2Sql and EF4 implementation.

2.3 – The Unit-of-work

So the steps up until now has been specific depending on the selected solution: L2Sql or EF4. How you consume the Unit-of-work isn’t solution specific, so from now on, there will only be one set off code examples.

Create the data source

When doing integration testing it’s very useful to be able to teardown and set-up a new database.

storageProvider.SetupDataStore();
Consume the Unit-of-work

Remember that the Unit-of-work is supposed to be short-lived. It contains the instance of the underlying DataContext and provides CRUD-operations.

Insert single

var customer = new Customer {Firstname = "Daniel", Lastname = "Wertheim"};

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Flush();
}

Insert many

var customers = new List<Customer>
                    {
                        new Customer {Firstname = "C", Lastname = "1"},
                        new Customer {Firstname = "C", Lastname = "2"}
                    };

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.InsertMany(customers);
    unitOfWork.Flush();
}

Update
There’s no real Update method, the way to see it is that either an entity belongs to the context (unit-of-work) or it doesn’t. If it where created in another context then the one you are using for updating it, you have to attach it to the new context. Sort of “letting the context be aware of the existence of the entity“. For this I use AttachAsModified.

var customer = new Customer { Firstname = "Daniel", Lastname = "Wertheim" };
            
using (var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Flush();
}

using (var unitOfWork = storageProvider.CreateUnitOfWork())
{
    customer.Firstname = "Scott";

    unitOfWork.AttachAsModified(customer);
    unitOfWork.Flush();
}

Delete
Just as with Update, if I work with entities created/fetched by another context (unit-of-work) I need to attach them to the new context. Although, when deleting, I don’t need to know each individual change of the entity’s properties, hence AttachMany will do.

var customers = new List<Customer>
                    {
                        new Customer {Firstname = "C", Lastname = "1"},
                        new Customer {Firstname = "C", Lastname = "2"}
                    };
            
using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.InsertMany(customers);
    unitOfWork.Flush();
}

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.AttachMany(customers);
    unitOfWork.DeleteMany(customers);
    unitOfWork.Flush();
}

Querying
For querying you just make use of the Query method, which returns an IQueryable. Hence you can write linq-expressions or use lambdas to query it.

var customers = unitOfWork.Query<Customer>().Where(c => c.Firstname == "Daniel").ToList()

3 – Wrap up

So this was kind of an simple introduction, but it gives you a starting point to elaborate from. If I will make a follow-up it will be about mappings. But until then, for EF4 you can read about my old writings about mappings (different model and different infrastructure code):

The L2Sql and EF4 implementations can be downloaded here. I have zipped the entire solution. The project you are interested in is “Pls.Core.Storage“.

//Daniel

Linq to Sql – How-to Separate the entities and the DataContext.

Updated See comments for details.

Yesterday we started to use Linq to Sql in a project at work. We didn’t select NHibernate but kind of wanted a clean model anyway, where the entities are separated and not bundled in the same class as the context. We also wanted clean entities: No partial methods; No (by us) unused INotify-interfaces. We also wanted the DataContext to live in an own assembly, so it’s not included in the assembly that holds the entities. Ok, so whith al these demands you probably think that NHibernate would be a better choice, well it wasn’t that hard to accomplish a solution that fullfilled our needs, and that’s what this post is about.

Demands:

  • Clean Entities (No partial methods, INotify-interfaces etc)
  • DataContext and Entities should live in different assemblies
  • No repositories, but one EntityStore, that uses a generic DataContext.

For this article I put together an example app, which is composed in VS2010. You can download it here. The example app has the following projects:

Some short notes about the projects:

  • Pls.Core: Should be seen as Microsoft-system lib. The code here has no coupling to a certain Domain.
  • Pls.Blog: Holds commonly shared resources within the application being built. E.g: Resources, Interface-definitions, Exceptions etc. In our case, nothing more than the IoC-container.
  • Pls.Blog.Domain: Holds code that are specific to the domain.
  • Pls.Blog.IoC.Configurations: Holds configuration used to bootstrap my StructureMap-based IoC-container.
  • L2SqlGenerator: Only used for generating the initial entities.

If I would have had specific EntityStore-implementations in the project, these would live in a own assembly: Pls.Blog.Storage. Since we are satisfied with the generic L2SqlEntityStore found in Pls.Core, this project is not needed.

T4-templates to the rescue

Damien Guard has put together some T4-templates (read more) that could be used to take control of how the DataContext and the entities are generated. All I did was to create a project that only has the responsibility of holding the DBML, and to make use of the T4-templates to generate the entities (it will also generate the DataContext, but I don’t care about that). These entities are then moved to the Domain-project and with a little work with ReSharper, the entities looks kind of slick. So the generated code is only used as a boilerplate. Of course you can tweak the T4-template to generate “perfect” code directly.

The solution

Step 1 – Download the templates
The templates are located at CodePlex: http://l2st4.codeplex.com/

You need two files from the ZIP:

  • L2ST4.ttinclude
  • [The language you are using, c# or VB.Net].tt

Step 2 – Setup a Generation project
I want to be able to work with the DBML-file and to customize the TT-file without affecting the application. Due to this I created an “dummy” project in my solution, named: “L2SqlGenerator”.

Add an DBML-file to this generation project. Then ensure that “Build Action = None” and that “Custom Tool = “.

Include the T4-files. Open the TT-file and check the options that Damien have included. I switched “FilePerEntity” to true and implemented a couple of my own options: [GenerateINotify, GenerateExtensibilityMethods, UseRegions].

Now add the tables and adjust the namespace for the entities in the DBML (property “Entity Namespace”, e.g Pls.Domain.Entities). Modify the model as you want: Naming of entities; Hiding of FK-properties etc. Whatever you want.

The DataContext and the entities should have been generated for you and lies beneath the TT-file. If they haven’t been generated/regenerated, right-click on the TT-file and select “Run Custom tool”.

Step 3 – Put the entities where they belong
Extract the entities and place them where you want them. In the example I have put them in “Pls.Domain.Entities” which lies in the “Pls.Domain-assembly”.

Pls.Blog.Domain.Entities.Entry

[Table(Name = @"dbo.BlogEntry")]
public class Entry
{
    private EntityRef<BlogContext> _blog;

    public Entry()
    {
        _blog = default(EntityRef<BlogContext>);
    }

    [Column(Name = @"Id", AutoSync = AutoSync.OnInsert, DbType = @"Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true, UpdateCheck = UpdateCheck.Never)]
    public int Id { get; set; }

    [Column(Name = @"BlogId", DbType = @"Int NOT NULL", CanBeNull = false)]
    private int BlogId { get; set; }

    [Column(Name = @"Title", DbType = @"NVarChar(100) NOT NULL", CanBeNull = false)]
    public string Title { get; set; }

    [Column(Name = @"Preamble", DbType = @"NVarChar(500)")]
    public string Preamble { get; set; }

    [Column(Name = @"Body", DbType = @"NVarChar(MAX) NOT NULL", CanBeNull = false)]
    public string Body { get; set; }

    [Association(Name = @"Blog_BlogEntry", Storage = @"_blog", ThisKey = @"BlogId", OtherKey = @"Id", IsForeignKey = true)]
    public BlogContext BlogContext
    {
        get
        {
            return _blog.Entity;
        }
        set
        {
            BlogContext previousValue = _blog.Entity;
            if ((previousValue != value) || (!_blog.HasLoadedOrAssignedValue))
            {
                if (previousValue != null)
                {
                    _blog.Entity = null;
                    previousValue.BlogPosts.Remove(this);
                }
                _blog.Entity = value;
                if (value != null)
                {
                    value.BlogPosts.Add(this);
                    BlogId = value.Id;
                }
                else
                {
                    BlogId = default(int);
                }
            }
        }
    }
}

Step 4 – Create a generic EntityStore
I like to have the actual “provider” that uses the entities to move data back and forth between the database in a sepparate assembly, e.g. “Pls.Storage”. In that assembly I add a namespace for the current provider-type, e.g. “L2Sql”. In this example app, I didn’t need it, since I’m using StructureMap, I could easily let the L2SqlEntityStore recide in Pls.Core.

Pls.Core.Storage.IEntityStore and Pls.Core.Storage.L2Sql.IUnitOfWork

public interface IEntityStore : IDisposable
{
    void EnsureCleanDatabase();

    IUnitOfWork<T> CreateUnitOfWork();

    IQueryable<T> Query<T>(Expression<Func<T, bool>> expression)
        where T : class;
}

public interface IUnitOfWork : IDisposable
{
    void Insert<T>(T entity) where T : class;
    void Update<T>(T entity) where T : class;
    void Delete<T>(T entity) where T : class;

    IQueryable<T> Query<T>(Expression<Func<T, bool>> expression) where T : class;

    void SaveChanges();
}

Thats the definition of the EntityStore-concept. Kind of simple. The implementation is not that hard either.

Pls.Core.Storage.L2Sql.L2SqlEntityStore

public class L2SqlEntityStore
    : IEntityStore
{
    protected static readonly object ContextLock = new object();

    private readonly MappingSource _mappings;

    public virtual string ConnectionString { get; private set; }
    protected virtual DataContext Context { get; private set; }

    public L2SqlEntityStore(string connectionString, MappingSource mappings)
    {
        _mappings = mappings;
        ConnectionString = connectionString;
        Context = CreateNewContext(_mappings);
    }

    public virtual void EnsureCleanDatabase()
    {
        lock (ContextLock)
        {
            if (Context.DatabaseExists())
                Context.DeleteDatabase();

            Context.CreateDatabase();
        }
    }

    public virtual IUnitOfWork CreateUnitOfWork()
    {
        var context = CreateNewContext(_mappings);

        return new L2SqlUnitOfWork(context);
    }

    public virtual IQueryable<T> Query<T>(Expression<Func<T, bool>> expression = null) where T : class
    {
        var table = GetTable<T>();

        return expression != null ? table.Where(expression) : table;
    }

    protected virtual Table<T> GetTable<T>() where T : class
    {
        return Context.GetTable<T>();
    }

    protected virtual DataContext CreateNewContext(MappingSource mappings)
    {
        return new DataContext(ConnectionString, mappings);
    }

    #region Object lifetime, Disposing
    ...
    #endregion
}

Pls.Core.Storage.L2Sql.L2SqlUnitOfWork

public class L2SqlUnitOfWork
    : IUnitOfWork
{
    protected readonly object ContextLock = new object();
    protected DataContext Context { get; private set; }

    public L2SqlUnitOfWork(DataContext context)
    {
        Context = context;
    }

    public virtual void Insert<T>(T entity)
        where T : class
    {
        var table = GetTable<T>();
        table.InsertOnSubmit(entity);
    }

    public virtual void Update<T>(T entity)
        where T : class
    {
        var table = GetTable<T>();
        table.Attach(entity, true);
    }

    public virtual void Delete<T>(T entity)
        where T : class
    {
        var table = GetTable<T>();
        table.DeleteOnSubmit(entity);
    }

    public virtual IQueryable<T> Query<T>(Expression<Func<T, bool>> expression)
        where T : class
    {
        return GetTable<T>();
    }

    public virtual void SaveChanges()
    {
        Context.SubmitChanges();
    }

    protected virtual Table<T> GetTable<T>()
        where T : class
    {
        return Context.GetTable<T>();
    }

    #region Object lifetime, Disposing
    ...
    #endregion
}

The actual Linq to Sql implementation of an EntityStore needs information about the mappings. The only support I have included, is support for Attribute-based mapping. You could of course use Xml-to. The mappings are resolved by looking for types that has the custom attribute “TableAttribute”. Instead of going throw all assemblies I pass in a prefix, so that only assemblies that has a name matching this prefix, will be scanned for types. This is controlled in the IoC-container.

Pls.Core.Storage.L2Sql.MappingSourceResolver

public MappingSource GetMappings(string assemblyPrefix)
{
    var mappings = new AttributeMappingSource();
    var model = mappings.GetModel(typeof(DataContext));
    var assemblies = AppDomain.CurrentDomain.GetAssemblies()
        .Where(a => a != null && a.FullName != null && a.FullName.StartsWith(assemblyPrefix));
    var mappingsFound = false;

    foreach (var assembly in assemblies)
    {
        var types = assembly.GetTypes()
            .Where(t => t.GetCustomAttributes(typeof(TableAttribute), true).Length > 0);

        foreach (var type in types)
        {
            model.GetMetaType(type);
            mappingsFound = true;
        }
    }

    if(!mappingsFound)
        throw  new DataException(string.Format("No attributemappings where found in any assembly with a name matching the prefix \"{0}\".", assemblyPrefix));

    return mappings;
}

Step 5 – Wire things up in the IoC-container
I have an IoC-container that is explicit for the application being built. The only thing it does is specifying an assembly that holds the bootstrap info.

Pls.Blog.IoC

public class BlogIoCContainer
    : StructureMapIoCContainer
{
    private readonly static string ConfigurationNamespace = typeof(BlogIoCContainer).Namespace + ".Configurations";

    public static IIoCContainer Instance
    {
        get { return Singleton<BlogIoCContainer>.Instance; }
    }

    protected override void BootstrapContainer()
    {
        Container.Configure(x => x.Scan(scanner =>
        {
            scanner.Assembly(ConfigurationNamespace);
            scanner.LookForRegistries();
        }));
    }
}

The configurations are really simple. I create a MappingSource by looking at assemblies having a name starting with “Pls.Blog”, hence the classes under “Pls.Blog.Domain.Entities” will be scanned and registered. The MappingSource is registrered as a singleton resource and the IEntityStore is mapped to the Linq to Sql implementation.

Pls.Blog.IoC.Configurations

[Serializable]
public class EntityStoreRegistry
    : Registry
{
    public EntityStoreRegistry()
    {
        Bootstrap();
    }

    private void Bootstrap()
    {
        var mappingsResolver = new MappingSourceResolver();
        var mappings = mappingsResolver.GetMappings("Pls.Blog");

        For<MappingSource>()
            .Singleton()
            .Use(mappings);

        For<IEntityStore>()
            .LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest))
            .Use<L2SqlEntityStore>()
            .Ctor<string>("connectionString").Is(ConfigurationManager.ConnectionStrings["Pls.Blog"].ConnectionString);
    }
}

Step 5 – Use the instrastructure
I have created a simple domain-object that has the responsibility to write entries to the blog. It uses the injected EntityStore to get a UnitOfWork and to add the entry. For brewity, I have left out validation.

Pls.Blog.Domain.BlogWriter

public class BlogWriter
    : IBlogWriter
{
    public IEntityStore EntityStore { protected get; set; }

    public BlogWriter(IEntityStore entityStore)
    {
        EntityStore = entityStore;
    }

    public virtual void WritePost(Entry entry)
    {
        using (var uow = EntityStore.CreateUnitOfWork())
        {
            uow.Insert(entry);
            uow.SaveChanges();
        }
    }
}

The BlogWriter is created via a DomainFactory. So the consumer code doesn’t go directly to the IoC-container, but via this factory. The DomainFactory uses the IoC-container, which is configured in the Pls.Blog.IoC.Configurations.DomainRegistry class.

Pls.Blog.Domain.DomainFactory

public class DomainFactory
    : FactoryBase
{
    public virtual IBlogInstaller CreateBlogInstaller()
    {
        return IoCContainer.GetInstance<IBlogInstaller>();
    }

    public virtual IBlogQuery CreateBlogQuery()
    {
        return IoCContainer.GetInstance<IBlogQuery>();
    }

    public virtual IBlogWriter CreateBlogWriter()
    {
        return IoCContainer.GetInstance<IBlogWriter>();
    }
}

The client

class Program
{
    static void Main(string[] args)
    {
        var domainFactory = new DomainFactory();

        var installer = domainFactory.CreateBlogInstaller();
        installer.SetupEntityStore();

        var blog = new BlogContext
                   {
                       Name = "The Blog", 
                       Owner = new Owner
                               {
                                   Username = "theuser", 
                                   Password = "p@ssword", 
                                   Firstname = "Daniel", 
                                   Lastname = "Wertheim", 
                                   Email = "none@none.xom"
                               }
                   };

        var writer = domainFactory.CreateBlogWriter();
        writer.WritePost(
            new Entry
            {
                BlogContext = blog,
                Title = "Normal",
                Preamble = "Check this out!",
                Body = "This is normal!"
            });

        var query = domainFactory.CreateBlogQuery();
        var post = query.Where(bp => bp.Title == "Normal").SingleOrDefault();

        Console.Out.WriteLine("Blog = {0}", post.BlogContext.Name);
        Console.Out.WriteLine("Owner = {0}", post.BlogContext.Owner.Name);
        Console.Out.WriteLine("Title = {0}", post.Title);

        Console.ReadKey();
    }
}

That’s it. May have looked a bit tricky, but download the code and see for yourself, it really isn’t that hard.

//Daniel