1

hope you can help!

I've started a project in MVC 3 and set the business domain model in another assembly, the interfaces define the contract between this assembly and all projects that will use it. I'm using Ninject to inject the dependencies into the project. I've hit a brick wall at the moment with a specific LINQ query.

    public IEnumerable<ITheInterface> DoMyQuery()
    {
        using (ISession session = _sessionFactory.OpenSession()) {
            var query = (
                from c in session.Query<IMyInterface>()
                where something == anotherthing
                group c by new { c.TheGrouper } into grp
                select new IMyInterface() {
                    Property = grp.Key
                }
            );

            return query.ToList();
        }
    }

Now obviously I can't instantiate an interface, but this is my problem! The only way around it is to instantiate the concrete class, but that breaks my rules of being loosely coupled. Has anyone else ran into this before?

I suppose my question is, how do I use "select new Object" in a LINQ query by using the interface and NOT the concrete class?

Note: just for the record, even if I do use my concrete class to just get it to work, I get an NHibernate error of "Could not resolve property: Key of: "... but that's another issue.

Any help appreciated!!

tereško
  • 58,060
  • 25
  • 98
  • 150
Paul Aldred-Bann
  • 5,840
  • 4
  • 36
  • 55

2 Answers2

2

Just using interfaces and DI container does not mean that you writing loosely coupled code. Interfaces should be used at application Seams, not for Entities:

A seam is a place where you can alter behaviour in your program without editing in that place

From Mark Needham:

... we want to alter the way that code works in a specific context but we don’t want to change it in that place since it needs to remain the way it is when used in other contexts.

Entities (domain objects) are the core of your app. When you change them you change them in place. Building Seam around your data access code however is a very good idea. It is implemented using Repository pattern. Linq, ICreteria, HQL is just an implementation detail that is hidden from consumers behind domain driven repository interface. Once you expose one of these data access technologies your project will be coupled to them, and will be harder to test. Please take a look at these two articles and this and this answers:

Community
  • 1
  • 1
Dmitry
  • 17,078
  • 2
  • 44
  • 70
  • Thanks for those links, very useful! This is a legacy project I'm working on and the data model is absolutely broken i.e. no primary keys, relationships between tables etc - basically using an RDBMS like a flat file system... – Paul Aldred-Bann Sep 28 '11 at 07:53
  • I've ended up having to use LINQ to SQL because NHibernate was giving very wrong results, I tested my LINQ queries in LINQPad and they were fine, but hibernate just didn't work - I assume it's because of the really broken data model. Tried the same queries in HQL, Criterion and LINQ, all the same wrong results! – Paul Aldred-Bann Sep 28 '11 at 07:54
0

I believe the call session.Query<IMyInterface>() is invalid because NHibernate is not aware of your intention that "some mapped class (implemented somewhere) is the right class to query".

To stay loosely coupled (new operator is a dependency) you should use factory pattern (DAO objects) responsible for creating (querying) concrete entities you need.

pkmiec
  • 2,594
  • 18
  • 16
  • Thanks for the help! I'm using the same thing elsewhere and it seems to work. It's only this isolated issue (because the only difference is I'm using "select new Object" instead of just "select " in my LINQ. However, factory pattern sounds interesting so I'll look into this! – Paul Aldred-Bann Sep 23 '11 at 15:26