LINQ and the DTO Tax

Thursday, December 20, 2007 by scott
0 comments

Jean-Paul Boodhoo's post on MappingEnumerable<T> reminds me how DTOs sometimes require an inordinate amount of effort for the simple jobs they perform. You need to define them, instantiate them, map them, groom them, and take them for walks twice a day. It always felt to me that the language should help to reduce the DTO tax, somehow.

In JP's post, he is using the following interface to define a mapper responsible for transforming domain objects into data transfer objects (screen bound DTOs, I'm assuming).

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

Where a simple implementation might look like:

public class DepartmentMapper : IMapper<Department, DepartmentDisplayItemDTO>
{
    
public DepartmentDisplayItemDTO MapFrom(Department input)
    {
        
return new DepartmentDisplayItemDTO()
            {
                ID = input.ID,
                Name = input.Name
            };
    }
}

LINQ takes some of the grunge work out of mapping DTOs. For example, if you aren't injecting a mapping strategy at runtime, LINQ can transform a Department object into a Department DTO in place:

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

Alternatively, when there is a mapper in play for more convoluted mapping logic:

IEnumerable<Department> departments = departmentRepository.GetAllDepartments();
return
  from d in departments
 
select departmentDisplayItemDTOMapper.MapFrom(d);

... which is equivalent to:

IEnumerable<Department> departments = departmentRepository.GetAllDepartments();

return departments.Select(d => departmentDisplayItemDTOMapper.MapFrom(d));

I think LINQ eliminates the need for JP's MappingEnumerable<T> (a DTO tax), while keeping the advantage of deferred execution (an item isn't mapped until it is enumerated).

Creating Silverlight Player Templates

Wednesday, December 19, 2007 by scott
0 comments

Pete Brown is a local guy with a great deal of Silverlight content on his blog, and some cool wallpaper downloads. Pete pointed to the Expression Encoder White Paper today. The document describes itself as providing the "best practices and methods for providing integrated and branded media player skins for Microsoft Silverlight".

After a quick read, I'd say the document does a fine job describing how to build custom skins and templates for the Silverlight media player. The techniques described in the document will also work with the ASP.NET Futures <asp:Media> control. Both of those controls provide additional features (like the standard VCR controls) on top of the Silverlight <MediaElement/>.

The document gets confusing, however, when it describes the class hierarchy behind the player. For instance:

_Button

Players generally require buttons. This is javascript functionality bound to XAML elements and handles mouse events and animations.

The _Button class handles binding the events and animations to the XAML. The intention is for you to handle the events you are interested in.

See the example above in "Roll your own controls" for details on how to implement your own buttons making use of _Button.

Cognitive dissonance comes into play several times in the document when the text describes how to consume underscored type like _Button. By convention, ASP.NET AJAX prefixes private fields, methods, and types with an underscore. When adding a new button to the player that is not one of the "well known" buttons (like the PlayPauseButton), it feels like a hack to instantiate or derive from an underscored class.

Personally, I've been a bit frustrated at the lack of extensibility in the player control provided by Expression. There are no public methods available to override the behavior of the Next, Previous, and VideoWindow button clicks, for example. I hope the ASP.NET Futures version of the control will flesh itself out a little more in the future.

Inheritance and the Entity Framework

Tuesday, December 18, 2007 by scott
1 comment

Here is an excerpt of the schema for the top level of OdeToCode:

The Community_ContentPages table carries all of the data needed by every type of content – like moderation flags, published date, and owner ID. Community_Articles carries just the extra information needed for a published article – like the article text itself.

Inside the code, Article and Book classes derive from ContentPage. Inheritance simplifies the implementation, because a great deal of the business logic applies to all the different types of content objects. For instance, the moderation and approval rules apply to articles, book reviews, comments, images, and other entities that all derive from ContentPage.

Mapping to Objects

Inheritance mapping is one good litmus test for the capabilities of an ORM product. LINQ to SQL, for example, only handles one of the three common strategies for modeling inheritance in an RDBMS – the "table per class hierarchy" strategy, which doesn't help me in this scenario. Most full featured OR/M products, like NHibernate, support multiple strategies, including the "table per subclass" strategy I need.

The Entity Framework documentation includes some pointers on table per subclass mapping (known as "table per type" or TPT in EF terminology). Although the EF designer is easy for getting tables and columns spit out into a mapping file, I found working with the designer a bit tedious. Trying to model inheritance using the designer created build errors, so I did most of the XML editing by hand. The key to TPT mapping is:

  • Use a BaseType attribute when defining EntityTypes in the conceptual schema.
  • Define a single Key column only on the base EntityType in the conceptual schema.
  • In the mapping specification, combine the EntityTypeMapping tags for all derived types into a single EntitySet:
<EntityContainerMapping StorageEntityContainer="dbo"
          
CdmEntityContainer="OdeToCodeEntityContext">
  <EntitySetMapping Name="ContentPages">
    <EntityTypeMapping
          
TypeName="IsTypeOf(OdeToCode.Core.Entities.ContentPage)">
      ...
    
</EntityTypeMapping>
    <EntityTypeMapping
          
TypeName="IsTypeOf(OdeToCode.Core.Entities.Article)">
      ...
    
</EntityTypeMapping>
  </EntitySetMapping>
</
EntityContainerMapping>


Querying

Once the XML work is done, it's relatively easy to pull out persisted entities.

Given the following DTO:

public class ArticleSummary
{
    
public int ID { get; set; }
    
public string Title { get; set; }
}

I can use the following LINQ query to pull out only Article objects. The trick is the OfType() operator:

IQueryable<ArticleSummary> articles =
   
from article in context.ContentPages.OfType<Article>()
   
select new ArticleSummary { ID = article.ID,
                                Title = article.contentPage_title };

Although I still have some reservations about EF, I'm warming up to the framework...

*If the naming convention strikes you as odd, then remember the schema was designed to work in a shared hosting environment where a single database might need to support multiple applications. The Community prefix helps to avoid naming collisions. An equivalent design today could use schemas in SQL 2005.

ALT.NET in Baltimore and D.C.

Wednesday, December 12, 2007 by scott
0 comments

Matthew makes the announcement in a blog post:

So, you may ask yourself, there are already groups out in the DC area, such as CapArea.NET, RockNUG, CMAP, DC XP Users group among others. They are great user groups that put on a lot of great events that I have attended time and time again and at some point presented at one of them. It's my belief that this group can supplement them nicely and help each other out. Many of these groups spend a lot of time talking about the new things coming from Microsoft. That's a very good thing, but that's not what we're aiming for. The goal of this group is to form very active discussion groups and find new and better ways to develop software. This group practices the Open Space Technology and encourages people to bring topics to talk about.

First meeting is this Thursday, Dec 13th.

Join the mailing list, and watch for the roaming meeting to reach a location near you in the D.C. / Baltimore metropolitan area.

The Greatest Challenge in Software Development

Monday, December 10, 2007 by scott
10 comments

... is choosing the right names.

Local variables need names. Instance variables need names. Methods need names, too, as do classes, columns, delegates, events, files, forms, parameters, projects, products, services, styles, tables, and of course – namespaces. Namespaces are nothing but a name! So many names, and so few words to use.

I was thinking about the amount of mental effort I expend in basic programming activities – like picking control structures (foreach versus do-while), or data structures (stacks versus lists), versus the amount of effort I expend to name all the abstractions in the simplest piece of software. Loops and structures are easy – naming requires a great deal of time and thought.

After all these years of thinking about names, I still struggle to pick the perfect name. Naming is a skill I need to improve - because names are important. I can use all the right patterns, have 100% test coverage, exceed every performance requirement, and still feel like I've failed if the names produce a piece of software that looks amorphous carbon:

Bad names kill good software by making the software un-maintainable.

Here are some interesting reads on naming:

I'd like to find more. Know of any others good ones?

Can I Replace JavaScript (and everything else) With Volta?

Friday, December 7, 2007 by scott
0 comments

In my last post, I looked at using managed code in Silverlight as a replacement for JavaScript and offered the following code as an example:

HtmlDocument document = HtmlPage.Document;
HtmlElement select = document.GetElementByID("mySelect");

for (int i = 0; i < 10; i++)
{
    
HtmlElement option = document.CreateElement("option");
    option.SetAttribute(
"value", "foo" + i.ToString());
    option.SetAttribute(
"innerHTML", "foo" + i.ToString());
    select.AppendChild(option);
}

In my opinion, the managed code API offers a sub-optimal experience relative to the plain and simple JavaScript that would implement the same functionality. To be fair, Silverlight's mission isn't to replace JavaScript, HTML, web browsers, and motherly love (as yet, I guess), but I wanted to explore the idea.

In an ironic twist, Microsoft's Live Labs released a preview of Volta this week with the following key messages:

  • Volta automates certain low-level aspects of distributing applications across multiple tiers, allowing programmers to devote their creative energy to the distinguishing features of their applications.
  • Via declarative tier splitting, Volta lets developers postpone irreversible design decisions until the last responsible moment, making it faster and cheaper to change the architecture to accommodate evolving needs.
  • Through MSIL rewriting, Volta follows developer's declarations to turn a single-tiered application into a multi-tiered application, generating boilerplate code for communication and serialization.

The first two bullet points make me uncomfortable. "Declarative tier splitting" sounds a lot like a movie I saw during the COM+ days. In that movie a hero by the name of "Location Transparency" was killed by 10 million chatty microbes from the Andromeda galaxy. It was a slow death, and a sad ending.

Two things sparked my interest in Volta, however. Seeing Erik Meijer at the helm of Volta was one, and MSIL rewriting was the second. There are MSIL re-writing tools available today (see the profiling API and Mono.Cecil as examples), but mainstream MSIL re-writing can bring many benefits to the CLR. One only has to look into Java land where bytecode modifications yield interesting possibilities for aspect oriented programming, inversion of control scenarios, application optimizations, and more.

The result was that I downloaded the new bits and gave Volta a spin. Volta can run client applications in the browser, so I continued the "how to kill JavaScript" bit by trying my C# code using the Volta programming model:

Select mySelect = Document.GetById<Select>("mySelect");

for (int i = 0; i < 10; i++)
{
    mySelect.Add(
new Option() { Value = "foo " + i.ToString(),
                                Text =
"foo "  + i.ToString()
                               });
}

... much closer to the model I was looking for, and it works in IE and FireFox, too.

Wait! What about the Document.GetByID method? Is that a static method on a static class just waiting to plunge a knife into the heart of a unit test? No – it turns out Document is a property on the Volta Page class that implements an IJavaScriptObject interface (hooray!). You can almost taste the testability, except that Document is a read-only property (boo!). I hope that the MSIL re-writing in Volta will give us the ability to inject mock Documents for testing.

It will be interesting to see how project Volta progresses.

by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!