TheChaseMan's Frenetic SoapBox

Always looking for better ways to do things...

Old School Architecture, Bleeding Edge Technology

For a while now I've been in "lurker" mode in all of the .NET community blogs. One of the interesting transitions that's been going on is the demo code for...well...just about everything including LINQ (whether it's the ADO.NET Entity Framework, LINQ-to-SQL, etc) or even ASP.NET MVC which includes using LINQ. Specifically, the removal of application "layers." Don't get me wrong, I think logically there's great patterns of cohesion to support the whole ability necessary for things like ASP.NET MVC's indirection. However sometimes, looking at this code (not to mention writing it) gives me a sense of going backwards into monolithic-type architecture. So I've been pondering from an architecture/design perspective how to implement all of this cool stuff but at the same time keep my mind at ease. So in playing around with Northwind (my favorite example database of all time :) )

  • Data Access Layer - Simply generate an ADO.NET Entity Framework Model  (.edmx)
  • Business Interface - This layer contains our use-cases where the UI leverages its services via messages, data structures, whatever makes sense.
  • Common Library - Since I don't like the idea of ADO.NET EF objects as my DTOs, I'd rather roll my own POJO (C#) objects (or even use DataTable or derivative of it).

//Common Library Assembly DTO Class

namespace Northwind.Common {

    public class CustomerEntity {

        public string Address { get; set; }

        public string City { get; set; }

        public string CompanyName { get; set; }

        public string ContactName { get; set; }

        public string ContactTitle { get; set; }

        public string Country { get; set; }

        public string CustomerID { get; set; }

        public string Fax { get; set; }

        public string Phone { get; set; }

        public string PostalCode { get; set; }

        public string Region { get; set; }

    }

}

 

//Business Interface (or Facade) Assembly

namespace Northwind.BusinessInterface {

    static public class CustomerInterface {

 

        static public List<Northwind.Common.CustomerEntity> GetAll() {

            using (var nwEntities = new NorthwindAPI.NorthwindEntities()) {

                var results = from custs in nwEntities.Customers

                              select new Northwind.Common.CustomerEntity() {

                                  Address = custs.Address,

                                  City = custs.City,

                                  CompanyName = custs.CompanyName,

                                  ContactName = custs.ContactName,

                                  ContactTitle = custs.ContactTitle,

                                  Country = custs.Country,

                                  CustomerID = custs.CustomerID,

                                  Fax = custs.Fax,

                                  Phone = custs.Phone,

                                  PostalCode = custs.PostalCode,

                                  Region = custs.Region

                              };

 

                Debug.WriteLine(((ObjectQuery)results).ToTraceString());

 

                return results.ToList();

            }

        }

    }

}

 

//Client Console App

namespace TestClient {

    class Program {

        static void Main(string[] args) {

            List<Northwind.Common.CustomerEntity> custs = Northwind.BusinessInterface.CustomerInterface.GetAll();

            custs.ForEach(c => Console.WriteLine(c.CustomerID));

        }

    }

}

 

This is nothing new as far as architecture ideas go - many designers are running into the same philosophical conflict, but what is interesting is the other questions it raises. When you've had tried-and-true methodologies for many years, it's difficult to simply jump ship and feel good about compiling LINQ queries into your code versus writing stored procs, or using ORM entities throughout your application versus creating more vanilla DTOs.  For something intended as only a Web application, how much do I care about tier separation versus logic-layers? We're assuming the application will end up only being a Web application. If it turns into a system that then needs to become published into a service, do you then refactor at that point, or do you plan ahead by separating layers as I'm inclined to do? What is the maintenance impact? How can we assume that our database is already designed and fleshed-out enough to the point where it is OK to use an ORM against it? Does this mean we design our database first? Generally it makes more sense to come up with our use-cases first, which is more of the BusinessInterface layer (and UI to some extent) before we identify what our system entity/attribute and data storage look like. If we start with use-cases (or tests for our TDD enthusiasts), will the database ever change during the development cycle? If so, will having to refactor my model and the corresponding ORM-generated classes have a significant impact on my team during development?

It is interesting stuff to think about. I'll keep lurking and see what others come up with too. Drop me a line if you have any interesting opinions on the subject. :)

 


Digg!

posted on Wednesday, June 03, 2009 10:15 AM

Feedback

No comments posted yet.