Archive

Posts Tagged ‘Entity Framework’

Entity Framework => Entity Base Class Library

November 23rd, 2008 stiiifff 5 comments

A few days ago the Entity Framework Team released a proposed solution for N-Tiers change tracking on entities … or should I call it a no-solution?

Basically, they will provide a low-level API that will allow YOU to do change-tracking the way YOU prefer.

5 months ago, I was writing a big NO to the Vote of no confidence. Well, now that I had to use Entity Framework on a real project, I must say that I was wrong. I really tried my best using it, thinking that it would be a safe bet for future evolution … and I know what I'm talking about when using ORMs, I'm a very advanced user of NHibernate (multi-tenancy, dynamic filters, dynamic mappings, partial domain models anyone?) … but my only conclusion to the Entity Framework is : WTF are they doing ?! Is that all you could come up with after months of research, brainstormings, experts meetings ?!

If someone give me a set of classes that doesn't bring a A to Z solution to a problem, sorry but I don't call it a Framework … I call it a Base Class Library. I've been vey supportive to the Entity Framework Team (I gave design feedback through multiple channels) but now I think I'm done. And it seems that others have the same feeling : Frans Bouma, author of the LLBGenPro ORM tool, goes in that direction too with its answer to the original post, and a full post on his blog, wich I both totally agree with.

I mean, come on, all those abstractions and discussions are very interesting but after some extensive periods of time trying to make this thing become useable, you have to ask yourself some serious questions. Even the now defunct Linq2Sql is more pleasant & easier to use.

Anyway, I will now go back using something that is customizable, extensible, that allow me to work the way I want (Domain-Driven Design) and most importantly that actually works : NHibernate. I recently discovered that it's moving full speed to version 2.1 with great new features such as Entity Modes : see here and there to know what I'm talking about. Also, a great workshop video on advanced use cases of NHibernate by Ayende.

Update: Ayende's reaction to the Entity Framework Team's design post.

Ado.Net Entity Framework – Vote of no confidence – NO !

June 24th, 2008 stiiifff No comments

Just stumbled on the new soap opera of summer 2008: the so-called Ado.Net Entity Framework Vote of No Confidence (that I will nicely abbreviate ANEFVONC). Come on, we have Euro 2008 Cup, the Olympic Games in China … isn't that enough ? ;)

The open letter describes the main problems that, following the Alt.Net community, currently prevent the Entity Framework from being a great DDD Tool:

  • INORDINATE FOCUS THE DATA ASPECT OF ENTITIES LEADS TO DEGRADED ENTITY ARCHITECTURES: Yes, EF is currently mainly about data access … let's hope it will evolve and introduce more & more 'Entity services'. Concerning Business Rules, is there a standard way of expressing Business Rules that EF could include ? Not sure about that but anyway I don't believe that EF currently prevents you to define your BR … because in a system with numerous & complex BR, your BR logic wouldn't be coded right inside your Entities. ;)
  • EXCESS CODE NEEDED TO DEAL WITH LACK OF LAZY LOADING: I remember EntitySet<T> has Lazy Loading built-in … but yeah, then you're not 100% PI compliant anymore. And no, I don't need Lazy Loading to keep my business logic free of Data Access concerns. I can use specific Repositories that will contain custom Linq queries if my base Linq-generic Repository is not enough. Lazy Loading is very appeling at first, but frankly, is only applicable to simple cases. 'Transparent data access' is a myth … you need to express a query in some form. Defining relations in order to benefit from Lazy Loading is a very simplistic view of the task of Querying on a Domain Model.
  • SHARED, CANONICAL MODEL CONTRADICTS SOFTWARE BEST PRACTICES: Haven't tested EF on that point … but indeed, support for Partial Models (see here, and here) is needed for complex Domain Models (especially when split in many Modules).
  • LACK OF PERSISTENCE IGNORANCE CAUSES BUSINESS LOGIC TO BE HARDER TO
    READ, WRITE, AND MODIFY, CAUSING DEVELOPMENT AND MAINTENANCE COSTS TO
    INCREASE AT AN EXAGGERATED RATE
    : Last time I checked, the EF Team had written a post on its blog to express its commitment to making EF as close to PI as possible … did they changed their mind ? Or is the Alt.Net community not patient enough? lol :)
  • EXCESSIVE MERGE CONFLICTS WITH SOURCE CONTROL IN TEAM ENVIRONMENTS: Well, let's hope it can be fixed.

Although, I think I understand most of the concerns expressed in the letter, I still feel that it focus too much on the data access part of Domain Driven Design … and DDD is so much more than that, right? IMHO, here are some key problems that must be adressed for DDD to hit mainstream:

  • Bridge the gap between DDD & MDD: I want to do DDD, but I don't want to know 100 patterns and tricks and tips in order to work efficiently … Gotta focus on defining the Ubiquitous Language right ? ;) What we need is a Meta-Model for DDD that allow us to create our Domain Models more easily than with Code, Unit Tests, Refactoring … I want to work at a higher level of abstraction, please. Give me DDD domain-specific languages !!! (a textual one for purists and a graphical one for realists, both being SCM-compliants).
  • DDD Best Practices Validation Rules: Create Generic DDD-specific rules that can be verified on the Domain Model created using the DDD DSL. Allow to define Domain Model-specific rules (= Business Rules) directly at the Model level, using a Business Rules DSL.
  • ORM-free DDD Code Generation: Well, if my first wish is realized (DDD DSL), then generate the code for me based on what I have described using the DSL. One way code generation would be fine (if they are enough extension points otherwise, we are back to square one with open letters and blah blah). Bi-Directional DSL would be great, but much much harder. Also, make the code generator pluggable … so that, any ORM-specific artefacts can be generated (keep the core DDD DSL free of any ORM-specifics). Also, generate Business Rules code.
  • Relationship as first-class elements of the language: let's get rid of those horrible Add / Remove methods hiding the fact that we are still not able to manage bi-directional relationships correctly & consistently. Make the concept of relationship an integral part of the language (Linq 2.0 ?). A great article on the subject (in french, sorry).

Other interesting (old !) posts that also shed light on the fact that DDD still has a long way to go: here and there.

Personnally, I think that EF is the first building block for more DDD goodness to come … so, give feedback, but be patient. I believe an annoucement like this one can only bring good things. Like NHibernate, Rome wasn't built in just one day.

Or did I miss something ? :)

Reminder: Never a sign a paper just because a lot of other people did it before you. ;)

Domain-Driven Design with Linq & ORM – Part 2

June 19th, 2008 stiiifff 2 comments

In my last post about DDD & Linq (1.5 month ago … oops), I showed the following piece of code:

ServiceLocator.Register<IUnitOfWorkFactory, NHibernateUnitOfWorkFactory>();

using (UnitOfWork.Start())
{
    ITransaction tx = UnitOfWork.Current.BeginTransaction(IsolationLevel.ReadCommitted);
    try
    {
        IRepository<Customer> cr = UnitOfWork.Current.GetRepository<Customer>();
        Customer customer = cr.FindOne(c => c.Id == "AROUT");
        customer.Address = "125 Hanover Sq.";
        cr.Save(customer);
        tx.Commit();
    }
    catch
    {
        if (tx != null) tx.Rollback();
    }
    finally
    {
        if (tx != null) tx.Dispose();
    }
}

After thinking about it, refactoring it 10 times, I sat down this morning and finally got it the way I wanted (don’t ask me why it took so long lol):

// Configure your favorite IoC container:
// - Register an IUnitOfWorkFactory
// - Register an IRepositoryFactory
// - Register a generic IRepository<TEntity>
//   (your container must support open generic types).
// - Configure your container to use the IRepositoryFactory
//   to create instances of the IRepository<TEntity> component
//   (your container must support factories).
// Once your IoC container is set up, configure it as the ServiceProvider
// (must implement the IServiceProvider interface or use a wrapper) for the ServiceLocator helper
ServiceLocator.ServiceProvider = container;

// Start a unit of work
using (IUnitOfWork uow = UnitOfWork.Start())
{
    // Get an instance of repository
    IRepository<Customer> cr = ServiceLocator.GetService<IRepository<Customer>>();

    // Retrieve data with a Linq query
    Customer customer = cr.FindOne(c => c.CustomerID == "AROUT");

    // Modify retrieved entity
    customer.Address = "000 Hanover Sq.";

    // Ask repository to save changes
    cr.Save(customer);

    // Mark the unit of work as complete to propagate changes to data source
    uow.Complete();
}

The re-worked IRepository<T> looks like this:

public interface IRepository<TEntity> : IDisposable where TEntity : class
{
    long Count();
    long Count(Expression<Func<TEntity, bool>> predicate);
    void Add(TEntity entity);
    void Add(IEnumerable<TEntity> entities);
    void Remove(TEntity entity);
    void Remove(IEnumerable<TEntity> entities);
    void RemoveAll();
    void RemoveAll(Expression<Func<TEntity, bool>> predicate);
    void Save(TEntity entity);
    void Save(IEnumerable<TEntity> entities);
    TEntity FindOne(Expression<Func<TEntity, bool>> predicate);
    IEnumerable<TEntity> FindAll();
    IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate);
    IQueryable<TEntity> QueryAll();
    IQueryable<TEntity> QueryAll(Expression<Func<TEntity, bool>> predicate);
}

I think it looks better ;) I currently have UoW & Repository factories for the following ORM:

  • NHibernate
  • ActiveRecord
  • LinqToSql
  • EntityFramework

The code is still very experimental, relies a lot of Castle Project‘s libraries (some might view it as a pro, others a con …), and I unfortunately don’t have much time to work more on it. If there is any interest for it, I might drop it online in its current state (basic samples, no unit test, code analysis spitting out a lot of warnings).

Feedback is welcomed. :)

Possible Improvements:

  • For simplification purpose, I might remove the dependency to a ‘ServiceProvider‘ and instead define a simple ‘UnitOfWork.Configure‘ method where we can specify the type of the IUnitOfWorkFactory & IRepositoryFactory.
  • Should the IUnitOfWork interface expose a ‘GetRepository<TEntity>‘ method to get rid of the ugly static call to ‘ServiceLocator.GetService<IRepository<T>>‘ ?

Why use the Entity Framework?

May 19th, 2008 stiiifff No comments

Danny Simmons has an interesting post on why would someone prefer using Entity Framework over plain Ado.Net, Linq to Sql or NHibernate. He makes some very good points in the first 2 comparisons … but well, those comparisons are not really fair anyway, for poor old Ado.Net and good but SqlServer-limited Linq to Sql.

When it comes to the comparison with NHibernate, we could have easily guessed the bottom line: Entity Framework, while maybe not as feature-complete & mature as NHibernate, comes with a graphical designer & related tools and thus provides a better overal integration with the .Net platform and Visual Studio.

Still, there is a point that leaves me a little bit confused about the Entity Data Model (EDM). Ok, this is a conceptual model … it brings a little bit more of Model Driven Development into the .Net platform. That's good.

But is it good enough for big projects with complex Domain Model(s) ??? Wouldn't teams working on such projects still prefer UML for conceptual modeling of the Domain, and invest in more advanced Model Driven Development techniques ? (custom model transformations, incremental code generation & reverse engineering, …).

Domain-Driven Design with Linq & ORM

May 1st, 2008 stiiifff 2 comments

We all now that an ORM plays an important role in a DDD architecture … but it would be nice if we could write our Domain Model without being tightly coupled to our favorite ORM tool, especially the code we write in Repositories. Thanks to Linq, we already have a way to abstract our queries (our ORM 'just has to' support Linq, anyway that's a requirement for a good ORM nowadays). The other thing we should be able to abstract is the object, specific to each ORM, that is the interface with the persistence layer, that keeps track of the changes on entities, the 'context' or the 'session' object.

Well, most ORM tools are implementing similar Patterns, namely UnitOfWork, IdentityMap, LazyLoad … so it is fair to assume that it should be possible to build an abstract layer that would allow us to work at a higher level, and have providers for our favorite ORM tools.

Here is a sample from some early code I wrote:

ServiceLocator.Register<IUnitOfWorkFactory, NHibernateUnitOfWorkFactory>();

using (UnitOfWork.Start())
{
    ITransaction tx = UnitOfWork.Current.BeginTransaction(IsolationLevel.ReadCommitted);
    try
    {
        IRepository<Customer> cr = UnitOfWork.Current.GetRepository<Customer>();
        Customer customer = cr.FindOne(c => c.Id == "AROUT");
        customer.Address = "125 Hanover Sq.";
        cr.Save(customer);
        tx.Commit();
    }
    catch
    {
        if (tx != null) tx.Rollback();
    }
    finally
    {
        if (tx != null) tx.Dispose();
    }
}

The Repository interface, which makes heavy use of Linq to express query criterions, looks like this:

public interface IRepository<TEntity> where TEntity : class
{
    long Count();
    long Count(Expression<Func<TEntity, bool>> predicate);
    void Delete(TEntity entity);
    void Delete(IEnumerable<TEntity> entities);
    void DeleteAll();
    void DeleteAll(Expression<Func<TEntity, bool>> predicate);
    void Save(TEntity entity);
    void Save(IEnumerable<TEntity> entities);
    TEntity FindOne(Expression<Func<TEntity, bool>> predicate);
    IEnumerable<TEntity> FindAll();
    IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate);
    IQueryable<TEntity> ProjectAll();
    IQueryable<TEntity> ProjectAll(Expression<Func<TEntity, bool>> expression);
}

Wanna use LinqToSql or EntityFramework instead of NHibernate … well, that’s easy, just change the first line to:

ServiceLocator.Register<IUnitOfWorkFactory, LinqToSqlUnitOfWorkFactory>();

or

ServiceLocator.Register<IUnitOfWorkFactory, EntityFrameworkUnitOfWorkFactory>();

Nice isn’t it ? ;)
We can also have:

ServiceLocator.Register<IUnitOfWorkFactory, ActiveRecordUnitOfWorkFactory>();

or

ServiceLocator.Register<IUnitOfWorkFactory, EussUnitOfWorkFactory>();

Well, I think you get the point.
So, what you think ? Suggestions & remarks are welcome.

“Not invented here” disclaimer: This code is largely inspired and based on code from Castle Project & Rhino.Commons. I just generalized it.

“Pre-Pre-Pre-Pre-Pre Alpha code” disclaimer: This code is quite experimental, it is not (yet) fully unit-tested and doesn’t support (yet) all the capabilities of the different ORM tools presented here.