views:

2011

answers:

3

I was avoiding writing what may seem like another thread on .net arch/n-tier architecture, but bear with me.

I, hopefully like others still am not 100% satisfied or clear on the best approach to take given today's trends and new emerging technologies when it comes to selecting an architecture to use for enterprise applications.

I suppose I am seeking mass community opinion on the direction and architectural implementation you would chose when building an enterprise application utilising most facets of today's .NET technology and what direction you would take. I better make this about me and my question, in fear of this being too vague otherwise; I would like to improve my architecture to improve and would really like to hear what you guys think given the list of technologies I am about to write.

Any and all best practices and architectural patterns you would suggest are welcome and if you have created a solution before for a similar type setup, any pitfalls or caveats you may have hit or overcome.

Here is a list of technologies adopted in my latest project, yep pretty much everything except WPF :)

  • Smart Client (WinForms)
  • WCF
    • Used by Smart Client
  • ASP.NET MVC
    • Admin tool
    • Client tool
  • LINQ to SQL
    • Used by WCF
    • Used ASP.NET MVC
  • Microsoft SQL Server 2008

Utilities and additional components to consider:

  • Dependency Injection - StructureMap
  • Exception Management - Custom
  • Unit Testing - MBUnit

I currently have this running in an n-Tier arch. adopting a Service-based design pattern utilising Request/Response (Not sure of it's formal name) and the Repository pattern, most of my structure was adopted from Rob Conery's Storefront.

I suppose I am more or less happy with most of my tiers (It's really just the DAL which I am a bit uneasy on).

Before I finish, these are the real questions I have faced with my current architecture:

  • I have a big question mark on if I should have a custom data access layer given the use of LINQ to SQL. Should I perform LINQ to SQL directly in my service/business layer or in a DAL in a repository method? Should you create a new instance of your DB context in each repository method call (using using())? or one in the class constructor/through DI?

  • Do you believe we can truly use POCO (plain old CLR objects) when using LINQ to SQL? I would love to see some examples as I encountered problems and it would have been particularly handy with the WCF work as I can't obviously be carrying L2S objects across the wire.

  • Creating an ASP.NET MVC project by itself quite clearly displays the design pattern you should adopt, by keeping view logic in the view, controller calling service/business methods and of course your data access in the model, but would you drop the 'model' facet for larger projects, particularly where the data access is shared, what approach would you take to get your data?

Thanks for hearing me out and would love to see sample code-bases on architectures and how it is split. As said I have seen Storefront, I am yet to really go through Oxite but just thought it would benefit myself and everyone.

Added additional question in DAL bullet point. / 15:42 GMT+10

+2  A: 

When I looked at Rob Connery's Storefront, it looked like he is using POCOs and Linq to SQL; However, he is doing it by translating from the Linq to SQL created entities to POCO (and back), which seems a little silly to me - Essentially we have a DAL for a DAL.

However, this appears to be the only way to use POCOs with Linq to SQL.

I would say you should use a Repository pattern, let it hide your Linq to SQL layer(or whatever you end up using for data access). That doesn't mean you can't use Linq in the other tiers, just make sure your repository returns IQueryable<T>.

Chris Shaffer
Thnx Chris. Yes I am returning an IQueryable<T> at the moment for maximum flexibility and the Repo did seem to hold my call to data neatly.
GONeale
POCO's are good if you wish to pass around a lightweight model representation and allow you to decouple from your DAL/ORM in case you wish to swap it anytime in the future. Plus they can be sent over WCF.
GONeale
I agree - I wouldn't tie the business logic directly to LINQ to SQL, and I'd advise the use of a Provider or some other abstraction in case you decide to switch later
RobS
Actually, IMO exposing IQuerable<T> or Expression on the repository interface is a bad thing - it makes the repository completely untestable in isolation.
Marc Gravell
Yes, the parallel model architecture in MVC Storefront _is_ silly. I would go so far as to call it an anti-pattern. If you want pure PI then use NHibernate or EF v2 when it comes out. Otherwise, you can get close to POCO with L2S - EntityRef/Collection is the only thing you need to keep.
Andrew Peters
Yeah I just started losing faith in Storefront towards the end, but Rob did try his best. I would love to hear more on EF v2... On another note, compelling argument Marc. Perhaps passing IQueryable<T> is not great; this is why I want POCO's, so they can be passed up and manipulated by LINQ instead.
GONeale
+3  A: 

To answer your questions:

  • Should I perform LINQ to SQL directly in my service/business layer or in a DAL in a repository method? LINQ to SQL specifically only makes sense if your database maps 1-to-1 with your business objects. In most enterprise situations that's not the case and Entities is more appropriate.

    That having been said, LINQ in general is highly appropriate to use directly in your business layer, because the LINQ provider (whether that is LINQ to SQL or something else) is your DAL. The benefit of LINQ is that it allows you to be much more flexible and expressive in your business layer than DAL.GetBusinessEntityById(id), but the close-to-the-metal code which makes both LINQ and the traditional DAL code work are encapsulated away from you, having the same positive effect.

  • Do you believe we can truly use POCO (plain old CLR objects) when using LINQ to SQL? Without more specific info on your POCO problems regarding LINQ to SQL, it's difficult to say.

  • would you drop the 'model' facet for larger projects The MVC pattern in general is far more broad than a superficial look at ASP.NET MVC might imply. By definition, whatever you choose to use to connect to your data backing in your application becomes your model. If that is utilizing WCF or MQ to connect to an enterprise data cloud, so be it.

Rex M
Thanks for your comments Rex. I probably can't answer the POCO question until I retry in my next project in the next couple of weeks.
GONeale
+1  A: 

Whether or not you use LINQ-to-SQL, it is often cmomon to use a separate DTO object for things like WCF. I have cited a few thoughts on this subject here: Pragmatic LINQ - but for me, the biggest is: don't expose IQueryable<T> / Expression<...> on the repository interface. If you do, your repository is no longer a black box, and cannot be tested in isolation, since it is at the whim of the caller. Likewise, you can't profile/optimise the DAL in isolation.

A bigger problem is the fact that IQueryable<T> leaks (LOLA). For example, Entity Framework doesn't like Single(), or Take() without an explicit OrderBy() - but L2S is fine with that. L2S should be an implementation detail of the DAL - it shouldn't define the repository.

For similar reasons, I mark the L2S association properties as internal - I can use them in the DAL to create interesting queries, but...

Marc Gravell