Mapping/Translation Layer ... Your thoughts?

G

Gregory A. Beamer

I am looking at making a "framework", of sorts, that is data access
technology agnostic. In order to completely go this route with .NET, I need
to add some sort of mapping or translation layer that maps from the .NET
types DataSets, LINQ, EF to domain objects. And, yes, EF 4.0 will be very
easy with the POCO bits.

What I am pondering now is the best way to link the objects together to keep
it so the business layer can consume without having to know the actual data
types. I have some ideas on this, but wanted to see what others thought to
get a sanity check. I had a suggestion from someone to pass the Repository
to the Translator and encapsulate it that way and another who suggested
creating an object that marries the two, both translator and repository
passed to an object that spits out domain objects. Both are highly testable,
but I am not sure I like the creation of another black box.

I am going to play, but thought it might be neat to get some feedback on
what other people think about the problem.

--
Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

************************************************
| Think outside the box! |
************************************************
 
A

Arne Vajhøj

I am looking at making a "framework", of sorts, that is data access
technology agnostic. In order to completely go this route with .NET, I
need to add some sort of mapping or translation layer that maps from the
.NET types DataSets, LINQ, EF to domain objects. And, yes, EF 4.0 will
be very easy with the POCO bits.

What I am pondering now is the best way to link the objects together to
keep it so the business layer can consume without having to know the
actual data types. I have some ideas on this, but wanted to see what
others thought to get a sanity check. I had a suggestion from someone to
pass the Repository to the Translator and encapsulate it that way and
another who suggested creating an object that marries the two, both
translator and repository passed to an object that spits out domain
objects. Both are highly testable, but I am not sure I like the creation
of another black box.

I am going to play, but thought it might be neat to get some feedback on
what other people think about the problem.

I don't think the particular usage is different from other encapsulation
problems.

You:
- create an interface
- create multiple implementations that translates between the
interface and the technology you want to use
- create a factory that create instances *or* use an IoC framework
to load implementations

Arne
 
M

Mr. Arnold

Gregory said:
I am looking at making a "framework", of sorts, that is data access
technology agnostic. In order to completely go this route with .NET, I
need to add some sort of mapping or translation layer that maps from the
.NET types DataSets, LINQ, EF to domain objects. And, yes, EF 4.0 will
be very easy with the POCO bits.

What I am pondering now is the best way to link the objects together to
keep it so the business layer can consume without having to know the
actual data types. I have some ideas on this, but wanted to see what
others thought to get a sanity check. I had a suggestion from someone to
pass the Repository to the Translator and encapsulate it that way and
another who suggested creating an object that marries the two, both
translator and repository passed to an object that spits out domain
objects. Both are highly testable, but I am not sure I like the creation
of another black box.

I am going to play, but thought it might be neat to get some feedback on
what other people think about the problem.


I use Data Transfer Object, an abstraction layer above the EF model. I
use mapping methods in both directions for a single DTO and its
associated EF object.

On the other hand, I use a smart Business Object as a DTO with the
mapping between BO and the EF object, with the Business Object smart
enough to know its state and how to persist itself to the Model via a EF
object.
 
G

Gregory A. Beamer

Arne Vajhøj said:
I don't think the particular usage is different from other encapsulation
problems.

You:
- create an interface
- create multiple implementations that translates between the
interface and the technology you want to use
- create a factory that create instances *or* use an IoC framework
to load implementations

There are a couple of things I can think that are different from some other
encapsulation problems.

1. Potential need for exposure of the underlying type up the line with IoC
The reason here is the translator, if sent in using an IoC pattern, will
require exposure to the data layer types
2. Quite easy to miss proper SOC, which leads us back to #1

Either way, after playing I have determined that you need an object above
the translator/mapping and access pieces that marries them. This particular
piece is going to be a bit harder to unit test, as it has to only expose the
models to the business classes, but I can test the translation with unit
tests and the data layer with integration tests, so testing the delivery of
an accessed and mapped type is not a big deal.

I am looking at genericizing a bit so I can actually test this marriage
piece, which currently looks something like this:

//{DataType} can be DataSets, LINQ objects or EF, etc
{DataType} dataType = Repository.GetById(id);
List<{DomainObject}> obj= Mapper.GetSingle(dataType);
return obj;

NOTE: No, this is not the naming in the real code, this is more pseudocode
than anything.

The number of lines of code mean the lack of a test is probably not as big
of a deal. Although I will refactor to a test, if possible.

--
Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

************************************************
| Think outside the box! |
************************************************
 
G

Gregory A. Beamer

Mr. Arnold said:
I use Data Transfer Object, an abstraction layer above the EF model. I use
mapping methods in both directions for a single DTO and its associated EF
object.

I am thinking along similar lines, although I think a simple encapsulated
translation to the domain object(s) is the simplest route. The initial
version of the project uses DataSets, as that is what the client is familiar
with. I have considered EF, but it really does not give me the most bang for
the buck until version 4.0, which has POCO (Plain Old CLR Objects) as entity
types.

But this project is just a testing ground, in many ways, as I feel the idea
of a proper translation/mapping pattern is useful across all data access
technologies, as most leave artifacts and lock you into a specific
technology. DataSets are obviously this way, as are LINQ to SQL objects.
This gravitates a lot of people to EF, but the currently released
implementation has artifacts of its own. I will hold judgment on EF 4.0 and
POCO until I have a chance to implement it in more than just a "playing
around" scenario, but the current EF adds some artifacts, including some
that are potentially costly if you work in a heterogeneous environment.

The easiest way, at least for now, is to have an object on top of the access
and translation/mapping piece that does the translation. This means
completely rebuilding part of that library if you switch technologies, or
coding multiple methods in a single library and adding configurability via a
factory pattern. But, rebuilding an encapsulated piece is refactoring as
long as the business layer does not have to be rebuilt, as you are not
changing contract, so it is a reasonable trade off.

I am thinking through how to make it more generic, so the impact on the
actual "marriage" object is lessened, but As soon as I add <T> to that
object, the business layer is aware of the underlying data access
technology, which begins to couple to the two layers. Not good. I could use
object, but I hate going that far down the call stack to make something more
generic.

At present, the wrapper concept appears to be the best, as it only impacts
the library in question. As nobody has spurred any other ideas, I think I
will continue down that route.
On the other hand, I use a smart Business Object as a DTO with the mapping
between BO and the EF object, with the Business Object smart enough to
know its state and how to persist itself to the Model via a EF object.

I am not as fond of "active record" type objects, as it breaks the domain
concept a bit and muddies concerns, at least in many cases. I tend to
gravitate towards domain entities that are purely state (no behavior), and
then use a Repository pattern. I have broken this in some cases, where it
made sense, but I try to stick to it whenever possible, as it is very
testable and leads to good SOC.

--
Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

************************************************
| Think outside the box! |
************************************************
 
M

Mr. Arnold

Gregory said:
I am thinking along similar lines, although I think a simple
encapsulated translation to the domain object(s) is the simplest route.
The initial version of the project uses DataSets, as that is what the
client is familiar with. I have considered EF, but it really does not
give me the most bang for the buck until version 4.0, which has POCO
(Plain Old CLR Objects) as entity types.

Yeah datasets are bad news. The mapping to a DTO in our projects are
simple. It's just a transfer of property data between the DTO and the
Model object. There is nothing fancy there. You have a mapping folder
with mapping classes dedicated to the Model object you need to map.
But this project is just a testing ground, in many ways, as I feel the
idea of a proper translation/mapping pattern is useful across all data
access technologies, as most leave artifacts and lock you into a
specific technology. DataSets are obviously this way, as are LINQ to SQL
objects. This gravitates a lot of people to EF, but the currently
released implementation has artifacts of its own. I will hold judgment
on EF 4.0 and POCO until I have a chance to implement it in more than
just a "playing around" scenario, but the current EF adds some
artifacts, including some that are potentially costly if you work in a
heterogeneous environment.

The things you have to understand with EF.

1) Views of the Model must be compiled every time you open it in code to
access it, which slows things down. You should use pre-complied views of
the Model, which speeds up querying the model. You can use Google and
find this information.

The other thing with using the EF in a multi user N-tier solution is the
lock of the underlying table being used. This can be done with a
'NOLOCK' in T-SQL, but NOLOCK to unlock it. With EF, it must be done
with System.Transaction with an isolation level "uncommitted read" must
be done, which can be found using Google.
The easiest way, at least for now, is to have an object on top of the
access and translation/mapping piece that does the translation. This
means completely rebuilding part of that library if you switch
technologies, or coding multiple methods in a single library and adding
configurability via a factory pattern. But, rebuilding an encapsulated
piece is refactoring as long as the business layer does not have to be
rebuilt, as you are not changing contract, so it is a reasonable trade off.

I guess. And sometimes it's better to keep things simple.
I am thinking through how to make it more generic, so the impact on the
actual "marriage" object is lessened, but As soon as I add <T> to that
object, the business layer is aware of the underlying data access
technology, which begins to couple to the two layers. Not good. I could
use object, but I hate going that far down the call stack to make
something more generic.

You have a problem there trying to make some kind of generic solution.
Some people like to do the mapping in the DAL. I like to send the EF
object to the BLL where the mapping is done and send the DTO, and the
BLL object has methods in it for List<T>.

What is needed is generic solution that can point to the EFM and make
the DTO(s) and Mapping classes with all the mapping in it. :)
At present, the wrapper concept appears to be the best, as it only
impacts the library in question. As nobody has spurred any other ideas,
I think I will continue down that route.


I am not as fond of "active record" type objects, as it breaks the
domain concept a bit and muddies concerns, at least in many cases. I
tend to gravitate towards domain entities that are purely state (no
behavior), and then use a Repository pattern. I have broken this in some
cases, where it made sense, but I try to stick to it whenever possible,
as it is very testable and leads to good SOC.


In WCF solutions, only state and no behavior is sent over the wire that
is the situation for me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top