Search code examples
asp.net-mvcdomain-driven-designdrydata-access-layer

asp.net MVC ddd DRY vs loose coupling and persistance/data access layer


So as I understand it with good loose coupling I should be able to swap out my DAL with a couple lines of code at the application root.

I have 2 DAL written, Linq-to-sql and a JSon file repository (for testing and because I wanted to try out the System.Web.Scripting.JavascriptSerializer).

linq to sql will create entities instead of my business models. and feed them upwards through an IRepository which is using constructor injection at the application root.

my JSon layer doesn't have any autogenerated classes from which to deserialize so I'm lost as to a simple way to have it depend on an interface or abstract class and still function.

This question is based on the following assumptions/understandings:

  • I believe I would need the linq to sql layer to implement an interface so the application domain at compile time can dictate that the entity classes are going to have a place to read/write all the current model's fields
  • Any Business logic dictates a need for another set of classes with almost the same names and same properties in the model layer
    • Then conversion methods that take the DALs objects and translate them to business objects and back would be needed. (even if both sides are implementing the same interface this seems very inefficient)
      • This code is yet another place that would have to make a change if the model class or interface changed (interface, business class, view, dal entity)
  • Deserialization of any alternative DALs requires I create 'entities' with the same properties and fields in that layer(more duplication)

So to meet all of the flexibility/agility goals it appears I need an interface for each application domain/business object, a concrete class where business logic can live, and DAL objects that implement the interface (this means layers that don't autogenerate entities would have to be hand coded pure duplication).

How would I use loose coupling without a ton of duplication and loss of DRY?


Solution

  • Not that I understand the problem correctly, but to solve duplicated classes you may use AutoMapper.

    Note that you may apply mapping declaratively or using reflection, i.e. semi-automatically. For example see here - this is not about data layer, but shows how simple attributes can help to automate mapping. In that case MVC applies attributes, but you may invent your own engine that looks for [Entity("Order")] attribute and applies AutoMapper.

    Also you cannot have 100% persistence independency with just "couple of lines". ORM selection plays big role here. For example Linq-To-SQL cannot use plain classes (POCOs) so it's not as easy to re-use them as with NHibernate, for example. And with Repository you're going to have many queries in the data layer; different ORMs usually have different query syntax or implementation (even Linq not always compatible between ORMs) so switching data access can be a matter of replacing data layer completely, which is not couple of lines (unless your app is "Hello, world!").

    The solution with AutoMapper above is actually a kind of self-baked ORM... so maybe you need to consider a better ORM that suites your requirements? Why don't you use EF4, especially given that it supports POCOs now, and is very similar to Linq-to-SQL, at least with query language?