3

I am trying to build a decoupled domain model. My (abstract) domain model defines an entity, 'Product' for example, and then my concrete SQL implementation provides a conversion method to that Domain entity.

For example:

public interface IDomainEntity<T> where T : class
{
    T ToDomainEntity();
}

My concrete SQL class then implements that interface:

public partial class Product : IDomainEntity<Domain.Product>
{
    public Domain.Product ToDomainEntity()
    {
        return new Domain.Product
        {
            ProductId = this.ProductId,
            ...
         };
    }
}

From my product domain service, I want to be able to expose a general filter method

public virtual IQueryable<T> Filter(Expression<Func<T, bool>> predicate)
{
   return GetAll().Where(predicate);
}

Where, in this case, T is of type Domain.Product. The problem I have is that in the SQL repository implementation, I need to convert the expression from type Domain.Product to type Sql.Product so I can use it against my Linq to Sql table.

Is it possible to take one expression base and convert it to another:

Expression<Func<Domain.Product, bool>>

to

Expression<Func<Sql.Product, bool>>

Apologies in advance if this doesn't make sense.

Neilski
  • 4,385
  • 5
  • 41
  • 74

2 Answers2

2

This is an interesting problem. If predicate were a functor instead of an Expression, the translation would be straightforward, but you would not be passing the Expression into the generated SQL, which I gather is what you want (for efficiency).

If Sql.Product and Domain.Product had a common interface, you could use that, but I gather from the question that you don't want to go that way.

I believe that leaves either: 1. "You can't do it," or 2. "You have to walk the expression tree and do the translation yourself." 2. may or may not be practical for you.

antlersoft
  • 14,636
  • 4
  • 35
  • 55
  • I'm using generics for most of the implementation, so I don't really want to introduce a class specific interface, though I could perhaps use inheritance on top of the base class to add a class specific interface to the implementation. Redefining the expression tree sounds interesting so will try and research that to see if it is a possibility - thanks for your help – Neilski Feb 08 '12 at 18:47
2

Even if what you want to do is possible, the real question should be: would anything be gained by doing this?

In my opinion, the Filter method is already one big leaky abstraction. Why is the filter input an Expression? Why isn't it just a 'normal' delegate? The only answer that comes to my mind is exactly that this is because the expression is required to map the predicate from its current form into something else, which isn't object-oriented.

So despite heroic efforts, the API still betrays that the underlying implementation is intended to be relational. In other words, it's not so decoupled after all.

Furthermore, the use of the IQueryable return type is also problematic for similar reasons.

Community
  • 1
  • 1
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • 2
    Hello Mark, I believe you may be directly responsible for my dilemma, I am currently reading your book 'Dependency Injection in .NET'. Having realised that I was in in fact Mary Rowan, the above came about through my efforts to make amends :-) What I was trying to do was to create a method that would allow the consumer greater flexibility in retrieving data - I guess I was trying to avoid having to create too many retrieval methods (with perhaps similar signatures) on the domain service. Thank you for the guidance - I will think again. – Neilski Feb 08 '12 at 21:36