Entity Framework 4 – Entity Dependency Injection

When dealing with a fat domain model, there is often a need to be able to inject different services into your entities.
e.g. you might want to inject some domain service like “ITaxCalcualtorService” or an infrastructure service like “IEmailNotificationService” into your entities.

If we rely completely on eager loading, then this is not a big problem, we can simply let or repositories iterate over each entity once we have fetched them from the DB and inject our services.
But when it comes to Lazy Load, we can no longer do this, in this case we need to get notified by the O/R mapper when an entity have been materialized so that we can inject our services into it.

If you are aiming to use Entity Framework 4 once it is released, you can accomplish this with the following code snippet:


..inside your own EF container class..

public MyContext()
    : base("name=MyContext", "MyModelContainer")
{
    ...
    ObjectStateManager.ObjectStateManagerChanged +=
    ObjectStateManagerChanged;
}

// this handler gets called each time the
// containers statemanager is changed
void ObjectStateManagerChanged(object sender,
                          CollectionChangeEventArgs e)
{
    // we are only interested in entities that
    // have been added to the state manager
    if (e.Action != CollectionChangeAction.Add)
        return;

    var state = ObjectStateManager
                    .GetObjectStateEntry(e.Element).State;

    // we are only interested in entities that
    // are unchanged (that is; loaded from DB)
if (state != System.Data.EntityState.Unchanged)
        return;

    OnEntityMaterialized(e.Element);
}

// this method gets called each time
// an entity have been materialized
private void OnEntityMaterialized(object entity)
{
    if (entity is Order)
    {
        Order order = entity as Order;
        // use property injection to assign 
        // a taxcalculator service to the order
        order.TaxCalculatorService =
SomeDIContainer.GetObject<ITaxCalculatorService>();
    }
}

The above is a very naïve example, but it does show how you can catch the materialization of a specific entity type and then configure that entity.

This allows us to add complex domain logic to our entities.
We can for example call a method like: “order.CalculateTotals()” where the CalculateTotals method now uses the ITaxCalculatorService.

HTH.

//Roger

4 Comments

  1. Cool stuff. Probably a better for .NET than NHibernate’s interceptors.

    I prefer to keep my service references outside of my entities though. But DI and use of Services is a big hassle in DDD that can mess up an otherwise clean domain model.

    I’ve tried to address this using what I’ve called transitory domain objects. I use them in front of the entities.

    http://blog.calyptus.eu/seb/2009/05/transitory_domain_object/

  2. Keith Patton says:

    Interesting, however i think if you have the need to inject services relating to email or other infrastructure needs, this is probably best done within the Application layer (in DDD terminology) rather than the core domain layer which should not involve itself with sending emails.

    I’ve created a post on how to implement a DDD driven architecture with EF including Dependency Injection here if you are interested:
    http://blog.keithpatton.com/2009/05/30/Entity+Framework+POCO+Repository+Using+Visual+Studio+2010+Net+40+Beta+1.aspx

  3. John says:

    (Feel free to move this to a post about EvoLisa) Could you by any chance share the source, or at least a binary, of your current fastest EvoLisa implementation (Dotfuscate it if you must)? I think I can beat it by a long way… My current implementation runs the first 5000 generations (with default settings) in 10 seconds on a Single Core of a Pentium 4 from 2004, and it continually runs 200-250 gen/sec with constraints of 50 polygons, each with 5 points (which keeps the performance consistent). The WPF port didn’t work out that well (I didn’t even try that hard, since RenderTargetBitmaps perform about the same function as your Renderer). I may still be able to speed it up to over 2000 (!!!) continuous generations per second on that same P4, and in the process make the code Embarrassingly Parallel, by using something a little more Direct to render the polygons. Once I do that, the major bottleneck will be the Fitness Function again, and I have a few tricks up my sleeve to improve that further (IL tell you more later). I think 1,000,000 generations in 15 seconds on a brand-new Core 2 Quad will be easily doable (more on that before summer’s end). Just e-mail me (starcalc AATT gmail DDOOTT com) if you want my further-improved source code and binary. Oh, and BTW, I’ve removed the need for cloning the drawing every generation by using a list of ints to track the changes.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s