Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

IMapper
BDD Specification Base Class
Nothin But .Net Store (Google Code) Breaking Change
MappingEnumerable
Refactoring (NAnt) for more readability

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 337
This Year: 62
This Month: 13
This Week: 3
Comments: 889

 Wednesday, December 19, 2007
Wednesday, December 19, 2007 10:26:48 PM (Mountain Standard Time, UTC-07:00) ( C# | Programming )

Got some feedback on my MappingEnumerable post. People wanted to see me leveraging some of the new language features (specifically linq).

I can leverage linq to change the extension method to eliminate the need for the MappingEnumerable (which was brought in to mitigate the absence of extension methods) and replace it with the following code: 

public static IEnumerable<Output> MapAllUsing<Input,Output>(this IEnumerable<Input> items,IMapper<Input,Output> mapper) { return from item in items select mapper.MapFrom(item); }

K. Scott Allen had the suggestion to use property initializers:  

IEnumerable<Department> departments = departmentRepository.GetAllDepartments(); return from d in departments select new DepartmentDisplayItemDTO() { ID = d.ID, Name = d.Name };

Which you can definitely do if you so wish, that specific dto is completely immutable so the above would not work, but could be changed to accommodate.

It is important to note that the IMapper<Input,Output> interface is an interface that can be implemented to perform all sorts of mapping. Some examples of how I have used this in the past are:

  • Mapping from DB to Domain
  • Mapping from Domain to DTO
  • Mapping from Errors to ScreenElements
  • Mapping from DTO to Presentation Model
  • ….

You are only limited by your imagination. And because each mapper has a single MapFrom method, it is very easy to test specific implementations of the interface, you can even create a non generic IMapper interface that you can use for completely reflective scenarios (picture externally defined OO mapping).

K. Scott Allen also mentions DTO Tax, and I don’t think his point is specific to just DTO’s but the cost of mapping in general. Focusing on 1 mapping at a time, refactoring out the duplication and moving on; is a way that you can grow and add all sorts of mapping in a very organic way to your applications.

Develop With Passion!!

Comments [3] | | # 
Wednesday, December 19, 2007 1:44:14 PM (Mountain Standard Time, UTC-07:00) ( C# | Programming )

With a newfound interest in leveraging the AutoMockingContainer (credit to James for convincing me of this approach) here is the code for my base class used to write BDD style interaction based tests:

public abstract class Specification { private MockRepository mockery; private AutoMockingContainer container; protected MockRepository Mocks { get { return mockery; } } protected AutoMockingContainer Container { get { return container; } } [SetUp] public void BaseSetup() { mockery = new MockRepository(); container = new AutoMockingContainer(mockery); container.Initialize(); Before_each_spec(); } [TearDown] public void TearDown() { After_Each_Spec(); } protected virtual void After_Each_Spec() { } public IDisposable PlayBackOnly { get { using (Record) { } return PlayBack; } } public void BackToRecord(object mockObject) { Mocks.BackToRecord(mockObject); } public IDisposable Record { get { return Mocks.Record(); } } public IDisposable PlayBack { get { return Mocks.Playback(); } } public abstract void Before_each_spec(); public Item CreateSUT<Item>() { return container.Create<Item>(); } public Interface CreateStrictMockOf<Interface>() { return mockery.CreateMock<Interface>(); } public IEnumerable<T> CreateMockEnumerable<T>() { return CreateMock<IEnumerable<T>>(); } public T Mock<T>() where T : class { return container.Get<T>(); } public void ProvideAnImplementationOf<Interface, Implementation>() { container.AddComponent(typeof (Implementation).FullName, typeof (Interface), typeof (Implementation)); } public void ProvideAnImplementationOf<Interface>(object instance) { container.Kernel.AddComponentInstance(instance.GetType().FullName, typeof (Interface), instance); } protected Interface CreateMock<Interface>() { return Mocks.DynamicMock<Interface>(); } }

I changed some of my original method names to match up with what Dave was doing (for a bit of consistency).Here is an example of a testfixture that leverages this as the base (this test happens to use an explicit CreateSUT method, vs the one provided by the AutoMockingContainer):

 

[TestFixture] public class When_told_to_visit_all_items : Specification { private IVisitor<int> visitor; private RichList<int> numbers; private IEnumerableActions<int> sut; private IEnumerableActions<int> CreateSUT() { return new EnumerableActions<int>(numbers); } public override void Before_each_spec() { numbers = new RichList<int>(); numbers.Add(1); numbers.Add(2); sut = CreateSUT(); visitor = CreateMock<IVisitor<int>>(); } [Test] public void Should_tell_visitor_to_visit_all_items_in_the_enumerable() { using (Record) { foreach (int i in numbers) { visitor.Visit(i); } } using (PlayBack) { sut.VisitAllItemsUsing(visitor); } } }

Develop With Passion!

Comments [1] | | # 
Wednesday, December 19, 2007 1:22:00 PM (Mountain Standard Time, UTC-07:00) ( C# | Programming )

I just upgraded the project to a VS2008 project and am now starting to demonstrate (and will continue to do so in the new year) how to integrate some of the new language features.

This means that if you don’t have .Net 3.5 installed on your machine you will not longer be able to run the NAnt build. Furthermore, if you do not have VS2008 on your machine you will not be able to open the solution.

Sorry!!

 

Develop with Passion!!

Comments [2] | | # 
Wednesday, December 19, 2007 11:03:44 AM (Mountain Standard Time, UTC-07:00) ( C# | Programming )

In my infrastructure layer of my projects I regularly include the following interface:

public interface IMapper<Input, Output> { Output MapFrom(Input input); }

This interface should be fairly self-explanatory, it takes in an item of type Input and spits out an item of type Output. For those who care about details (and I do) it is also good to note that this interface matches the signature for a Converter generic delegate.

One of the (many) places that I use implementations of this interface is in the service layer to marshal data back up to the higher level layers as DTOS. Here is an example of a simple Mapper:

public class DepartmentDisplayItemDTOMapper : IDepartmentDisplayItemDTOMapper { public DepartmentDisplayItemDO MapFrom(IDepartment department) { return new DepartmentDisplayItemDO
(department.Name, department.Id); } }

One of the ways that I would have leveraged this in the past would have been to inject the service layer component with the appropriate mapper and then map items that were returned from the repository in place.

Here is another alternative that takes advantage of a type I am calling a MappingEnumerable<T>. Take a look at the code for the class:

public class MappingEnumerable<Input, Output> : IMappingEnumerable<Input, Output> { private IMapper<Input, Output> mapper; private IEnumerable<Input> inputItems; public MappingEnumerable(IMapper<Input, Output> mapper, IEnumerable<Input> inputItems) { this.mapper = mapper; this.inputItems = inputItems; } IEnumerator<Output> IEnumerable<Output>.GetEnumerator() { return MapAllFrom(inputItems).GetEnumerator(); } public IEnumerator GetEnumerator() { return ((IEnumerable<Output>) this).GetEnumerator(); } private IEnumerable<Output> MapAllFrom(IEnumerable<Input> input) { foreach (Input item in input) { yield return mapper.MapFrom(item); } } }

Using this class from the service layer is as simple as:

 

public IEnumerable<DepartmentDisplayItemDO> GetAllSubdepartmentsOf(long departmentId) { IDepartment parentDepartment = departmentRepository.FindBy(departmentId); IEnumerable<IDepartment> subdepartments = departmentRepository.AllSubDepartmentsOf(parentDepartment); return new MappingEnumerable<IDepartment, DepartmentDisplayItemDO> (subdepartments, departmentDisplayItemDTOMapper); }

Notice that the MappingEnumerable decorates the existing enumerable with mapping behaviour. Because the MappingEnumerable is itself an implementation of an IEnumerable<T> interface, the mapping of each item will not start until the iteration of the enumerable happens.

Taking this class and applying it in the 3.5 world (I prefer using components vs free floating extension methods) can result in the following:

IDepartment parentDepartment = departmentRepository.FindBy(departmentId); IEnumerable<IDepartment> subdepartments = departmentRepository.AllSubDepartmentsOf(parentDepartment); return subdepartments.MapAllUsing(departmentDisplayItemDTOMapper);

Where MapAllUsing is an extension method on IEnumerable which lives in my infrastructure layer. The simplified implementation of MapAllUsing just delegates the work to the MappingEnumerable class: 

public static IEnumerable<Output> MapAllUsing<T,Output>(this IEnumerable<T> itemsToMap,IMapper<T,Output> mapper) { return new MappingEnumerable<T, Output>
(mapper,itemsToMap); }

One more short example to show how I leverage this pattern in my apps take a look at this method on a DatabaseGateway interface:

IEnumerable<DataRow> GetASetOfRowsUsingA(IQuery query);

A simple method to return an enumerable of DataRows. You can now leverage this to do things like:

public IEnumerable<DomainObject> GetAllUsing(IQuery query) { return gateway.GetASetOfRowsUsingA(query).MapAllUsing(dbMapper); }

Where the mapper in this case knows how to hydrate datarows into domain objects of the specific (DomainObject) type the mapper is defined for.

One of the things I tell people in class (and work) is that IEnumerable is the ultimate Separated Interface and this post just scratches the surface of the things you can do by just getting creative with the IEnumerable interface.

Develop With Passion!!

Comments [2] | | # 
 Monday, December 10, 2007
Monday, December 10, 2007 11:35:49 PM (Mountain Standard Time, UTC-07:00) ( Continuous Integration )
Adam just recently posted about refactoring NAnt build files to introduce a much clearer understanding of NAnt and associated build files for people who may not be familiar with typical NAnt style naming conventions. I am definitely a culprit of the style of naming that he dislikes (when it comes to my NAnt files!!), and will definitely take his recommendation to heart when introducing NAnt in the future!!
Comments [0] | | #