NAVmoble - the pocket-sized ERP
Optimized for Microsoft Dynamics NAV and Windows Mobile powered devices

Thursday, July 27, 2006

LLBLGen 2.0 - Implementing Entity Factory Mapper

We've just finished upgrading our current project to LLBLGen v2.0. It provides a lot new features including some .NET 2.0. goodies. One of these new stunning features is the support for generic entity collections. Our project involves development of ASP.NET based application framework, which needs to construct and fetch entity collection run-time (Adapter scenario).

The common pattern for doing this with LLBLGen 2.0 in the Adapter scenario is like this:

EntityCollection<CustomerEntity> customers = new EntityCollection<CustomerEntity>(new CustomerEntityFactory());
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntityCollection(customers);



We've got a class called DataAccessManager, which is intended to be used like this:
EnityCollection<CustomerEntity> customers = DataAccessManager.FetchEntityCollection<CustomerEntity>(null);

...and the implementation(simplified version):

   public static class DataAccessManager
  {
      ..
         public static EntityCollection FetchEntityCollection(IPredicateExpression expression) where T : EntityBase2
         {
            EntityCollection collection = new EntityCollection();
            Type factoryType = EntityFactoryMapper.GetFactoryType(typeof(T));
            IEntityFactory2 factory = (IEntityFactory2)Activator.CreateInstance(factoryType);
            collection.EntityFactoryToUse = factory;
            DataAccessAdapter adapter = new DataAccessAdapter(connectionString);
            adapter.FetchEntityCollection(collection,expression);
            return collection;
         }
   }


The problem in the upper implementation is that we haven't found "out of the box" mechanism to map EntityBase2 type to IEntityFactory implementation. So we've managed to generate such a class by adding a new LLBLGen template.

We wanted to have our mappign pattern like this:
Type t = typeof(CustomerEntity);
IEntityFactory2 entityFactoryType = EntityFactoryMapper.GetFactoryType(t);


and the implemenation like this(not quite elegant solution):

   public class EntityFactoryMapper
   {
      public static Type GetFactoryType(Type entityType)
      {
         if(entityType == typeof(CustomerEntity))
            return typeof(CustomerEntityFactory);
         else
            if(entityType == typeof(OrderEntity))
               return typeof(OrderEntityFactory);
                  else
                  ....


In order to this we've created a new template file:
[DEVICE]:\Program Files\Solutions Design\LLBLGen Pro v2.0\Templates\SharedTemplates\Net2.x\C#\FactoryMapper.template

and we've added the following lines :
using System;
namespace <[RootNamespace]>
{

///


//Entity-Type To EntityFactory Type mapper
///

using YourProjectNamespace.EntityClasses;
using YourProjectNamespace.FactoryClasses;

   public class EntityFactoryMapper
   {
      public static Type GetFactoryType(Type entityType)
      {
         <[Foreach Entity CrLf]>
         if(entityType == typeof(<[CurrentEntityName]>Entity))
            return typeof(<[CurrentEntityName]>EntityFactory);
         else
            <[NextForeach]>
               return null;
      }
   }
}

After generating the code again we've received our new class EntityFactoryMapper ready for usage

No comments: