Data Transfer Objects


Data Transfer Objects Pattern

Data Transfer Objects (DTOs) are a necesarry time-sink when working with SOA.  Proper SOA dictates that you must not pass domain objects across service boundaries.  In many cases, such as when using an ORM, it is extremely difficult to pass your domain objects across the service boundaries even if you choose to disreguard the SOA guidance.  Also, there may be good reasons why you do not want to make your domain objects serializable.

DTOs Defined

So what exactly are DTOs?  They are objects that have no behavior outside of accessors and mutators of their properties.  Often times DTOs line up one-to-one with domain objects as in the following example.

/// <summary>

/// Domain Object

/// </summary>

public class Company
{
private string name;
private string taxId;

public Company(string name, string taxId)
{
this.name = name;
this.taxId = taxId;
}

public string Name { get { return name; } }
public string TaxId { get { return taxId; } }
}

/// <summary>
/// Data Transfer Object
/// </summary>
public class CompanyDTO
{
public string Name { get; set; }
public string TaxId { get; set; }
}

Other times DTOs may need to carry data for a request that has no direct representation as a single object in the domain.  Consider a service that needs to expose data about a company and its owner.  Obviously the clients shouldn't have to request data about the company and then data about the owner in a separate request.  Doing so would incur the costs of two round trips, and the owner data is a part of a single logical unit as exposed by the service.

/// <summary>

/// A company
/// </summary>
public class Company
{
private string name;
private string taxId;

public Company(string name, string taxId)
{
this.name = name;
this.taxId = taxId;
}

public string Name { get { return name; } }
public string TaxId { get { return taxId; } }

public Owner Owner { get; set; }
}

/// <summary>
/// Owner of a company
/// </summary>

public class Owner
{
public Company Company { get; set; }

public string FirstName { get; set; }
public string LastName { get; set; }
}

/// <summary>
/// Data Transfer Object

/// </summary>
public class CompanyDTO
{
public string Name { get; set; }
public string TaxId { get; set; }

public string OwnerName { get; set; }
}

From Domain Object to DTO and Back Again

The assembler pattern, a subset of the mapping pattern, is used to translate DTOs to and from domain objects.



It is possible to create a reusable conventions based assembler.  I will talk more about this in the future.  For small projects, the cost of creating assemblers for the DTOs is trivial.  For larger ones, it is still worth the effort for the sake of encapsulation.

/// <summary>

/// Assembler for Company and CompanyDTO.

/// </summary>
public interface ICompanyAssembler
{
CompanyDTO Convert(Company company);
Company Convert(CompanyDTO DTO);
}

What is so useful about an object that has no behavior?

DTOs may seem like weak objects because of their lack of behavior; but this is what makes them the one object that is safe to pass across a service boundary.  A client that interacts with your service may, and often will, have a different domain from the service itself.  In fact, many different clients with many different domains may interact with your service.  It is difficult and undesirable to share the same domain model between a service and all its potential clients. 

Consider again the Company example.  Let us assume that the service we are writing is a better business bureau catalog of companies.  The domain object, Company, may include such methods as "FileComplaint" or "RevokeLicense." 

This service may be consumed by an auction site that wants to use the companies names and ratings but has no need to file complaints and does not have the ability to revoke a license.  The company domain object for the auction site will include methods such as "AddAuction" or "AssociateWithReview." 

Sharing the domain objects between the auction site and the better business bureau service would pollute both domains; not to mention the fact that they may, and in this example certainly would, have different owners who do not wish to share code bases.

Sharing DTOs, because of their lack of behavior, works fine though.  The DTOs serve as a simple, abstracted definition for the data that the service and its clients must exchange.



DTOs also insulate your service clients from changes to the domain of the service and vice versa.  You are free to change your domain objects as much as you want and leave the DTOs alone.  The assembler can simply be updated as the domain objects are updated.

If the domain objects were shared by the clients, every change to a domain object would directly impact clients, greatly increasing the costs of maintaining the service.

kick it on DotNetKicks.com

author: Nathan Stott | posted @ Saturday, August 23, 2008 11:08 PM | Feedback (0)

MVC Forms WIth Validation Open Sourced


I've set up a google code repository here for the ASP.NET MVC Forms With Validation framework I discussed in this post.

I have made some alterations to it since the post that I will review in a later posting.

Briefly, the major changes are as follows:
  1. Multiple fieldsets are now supported in the forms.
  2. I have taken the first steps towards supporting objects that contain child objects.  A 1-1 relationship is supported in the current revision.  A new fieldset is generated for each child object.
  3. Strategies have been revamped so that they no longer are mapped to types.  Now a strategy is allowed to return null if it does not want to handle a property descriptor passed to it.  If it returns null, the next strategy in the list will be tried.
Check it out.  Tell me what you think.  I am accepting patches and if you want to be a contributor, contact me through the contact form on this blog.

kick it on DotNetKicks.com

author: Nathan Stott | posted @ Sunday, August 17, 2008 4:25 PM | Feedback (0)

Forms Framework with Validation for ASP.NET MVC


Update: This project has been open sourced.  See details in this post.

One thing that is notably missing from ASP.NET MVC is a good way to handle forms and their validation.  To resolve this issue, I started on a simple forms framework this weekend.

The end goal



I don't particularly like the action filter to handle the insertion of the model as a parameter.  I would prefer it be done via windsor and interceptors; however, for the first go round I have decided to keep the castle stack out of this.  The technique could easily be adapted to use MVC Contrib's WindsorControllerFactory and interceptors so that attributes do not have to be on every action you wish to use a form helper with.  More on that later.

For those of you who want to skip the reading and get straight to the code, download the sample project.  Look at the /Home/Contact page.  Note: the sample project depends on MVC Preview 4.

The Components

  • Field - A field is the smallest unit of input and validation in a form.
  • Widget - A widget is an abstraction of HTML template text for input.
  • FormBase - Base class for form helpers.
  • ModelForm - A form auto created from a POCO model.

Widget

A widget has a name, a value, and some attributes.  The name and value properties are by default shortcuts to the name and value attributes of the widget's attribute collection.  However, this behavior is overridable in subclasses.  A widget also has a way of rendering itself as XHTML.

Field

A field has a name, a value, and a widget.  By default a field is required, and it has a publicly exposed validate method so that it can be asked to validate its value.  It also has the ability to output itself as XHTML. 

FormBase

FormBase, the base class for forms contains a collection of fields, a method to validate the fields, and a method to load the values of fields from a name value collection.  The latter facilitates the loading of data from a browser request.

The first concrete implementation of FormBase I created was ModelForm.  A ModelForm accepts a generic type argument and in its constructor takes an object of that type.  It uses this object to generate fields for the form.  The generation logic is implemented using the strategy pattern so that it is easily customizable.

Here is the strategy interface



The ModelForm registers default strategies



The constructor allows you to pass in your own strategies



With that, we have everything we need to make a form from a POCO.

Model Action Filter

One of the neatest things ASP.NET MVC does is allow you to make controllers with parameters that will be filled in from the request. 

I wanted to be able to do this with my form classes as well.

For the first go round, I decided not to use what I would prefer: Windsor and IInterceptors.  Instead I integrated the MVC way by using their action filters.

The filters give us everything we need to set the values for a parameter.  We have access to the parameters through the ActionMethod.GetParmaeters() method and we can set the parameters via the ActionParameters dictionary.

Here is the action filter



FormFactory is a simple helper class that uses a strategy pattern to create forms based upon the type passed in and a NameValueCollection.

Settings filterContext.Action

Now, this action will work!



Rendering the Form in a View

I provided three canonical methods for rendering the form:

AsDiv - renders the form with each field wrapped in a div
AsTable - render the form with each field as a table row
AsList - render the form with each field as a list item of an unordered list

I also provided a AsCustom method that allows you to specify an XElement to wrap the form fields inside of and an XElement to use as the parent for the children generated by the field instances.

If you want even more flexibility, the rendering is completely overridable by subclassing.

Rendering the form is as simple as passing it to a view and calling AsDiv() or your preferred alternative.

All output is valid XHTML.  Invalid fields receive an error class.

Rendered


Validation


Download the Sample Project
Note: the sample project depends on MVC Preview 4.

kick it on DotNetKicks.com

author: Nathan Stott | posted @ Sunday, August 10, 2008 12:08 PM | Feedback (13)

Building NHibernate From Source


Recently, on nhusers, the NHibernate users mailing list, I've seen questions from people wishing to get started building NHibernate from source.  Some people are unfamiliar with open source in the .NET world and the tools used for it, so I made this beginner level screencast about how to get started building NHibernate from source.

You can download the screencast here.

Here is a list of the prerequisites you will need to follow along:
For reference, you can find the official NHibernate document about getting started from source here.

Note: I realized after I posted this that I forgot to provide a link to the free codec needed to view this screencast.  You will need to d/l the free camstudio lossless codec (here) to view this video.  Extract the files, right click on the .inf, and select install.  You will receive a warning, but it's ok.  This is a widely used screencasting codec and you can find a lot of info about it via google.
In the future, I'm going to convert my videos to flash and stream them to make things easier all-around.
Sorry for the inconveniance.

author: Nathan Stott | posted @ Monday, August 04, 2008 8:13 AM | Feedback (2)

MVC Routing for Alternate Response Types


I'm working on my first project using asp.net MVC. 

I came across what is probably a common desire amongst MVC developers: the ability to serve a client a response type of its choice.  I wanted to do this by specifying the desired type in the URL and keeping the URLs pretty.

Here are how I wanted the routes to look:

  • /Home/Index - return HTML view
  • /Home/Index.xml - return xml view
  • /Home/Index.json - return json view
With the routing with asp.net MVC, this was simple.

I added this to RegisterRoutes after the default route in global.asax:
routes.MapRoute(
"SpecifyType",
"{controller}/{action}.{responseType}/{id}",
new { controller = "Home", action = "Index", id = "", responseType = "html" }
);
I also changed the default route to this:

routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "", responseType = "html" },
new { action = @"\w+" }
);
Now in the controllers you can check for the desired response type as such:

string responseType = RouteData.Values["responseType"]

This could be encapsulated into a controller base class to make things cleaner.  I'll leave that to the reader.

 kick it on DotNetKicks.com

author: Nathan Stott | posted @ Tuesday, July 29, 2008 5:17 PM | Feedback (2)

NHibernate Bulk Updates/Inserts/Deletes with Named Queries


There was an interesting thread on the NHibernate users mailing list this week where Fabio Maulo advised the use of NHibernate named queries to a user who was experiencing severe performance issues with a bulk update scenario.

This is great stuff, and I have ignored named queries almost completely in the past.

using(ISession s = OpenSession()) {
using (ITransaction tx = s.BeginTransaction())
{
IQuery sql = s.GetNamedQuery("native-delete-car").SetString(0, "Kirsten");
sql.ExecuteUpdate();
tx.Commit();
}
}

That is Fabio's example of executing the named query.  This was the mapping for the query:

<sql-query name="native-delete-car">
        <synchronize table="VEHICLE"/>
        delete from VEHICLE where Owner = ?
</sql-query>

*As Fabio so helpfully pointed out in my over eagerness posting this I ignored that this is indeed a SQL statement.  The sql-query element name should've given it away I think :). 

Here's an example of an HQL one:

<query name="delete-car">
   <![CDATA[
       delete Vehicle v where v.Owner = :owner
   ]]>
</query>

note: ExecuteUpdate is currently not supported for HQL queries.  This was the only JIRA I could find about this issue.  Looks like we're waiting on Ayende to work some magic before we have this support.

It may not look very ORMish.  Some of you may be saying, "What's the point of using an ORM at all if we're just writing SQL."  Well, that's not SQL, that's HQLHQL is not as nice as the criteria API, but it's a step above straight SQL.  Also, there are some things you can express with HQL that you can not express with the Criteria API.

Castle ActiveRecord users are not left out in the cold either.  ActiveRecord can also cleanly express named queries.  Check out the castle page on ActiveRecordBaseQuery (here).

Also, the prolific Oren Eini has a post (here) about named queries.

author: Nathan Stott | posted @ Monday, July 28, 2008 2:16 PM | Feedback (2)

BooLangStudio progress


BooLangStudio is a CodePlex project to provide Visual Studio integration for the Boo language

author: Nathan Stott | posted @ Friday, July 18, 2008 9:18 PM | Feedback (0)

Syntax Teaser


Here is a taste of one of my dogfooding test cases for Mite:

Up:
    CreateTable @Document:
        Int32 @Id, { @primary : true, @identity : true }
        Guid @Uid, { @rowguid : true }
        String @Name, { @length : 55 }
        String @Description, { @length : 100 }
   
    CreateTable @CatalogNode:
        Int32 @Id, { @primary : true, @identity : true }
        Guid @Uid, { @rowguid : true }
        String @Name, { @length : 55 }
        String @Description, { @length : 100 }
        ForeignKey @Document, { @nullable : true }

Down:
    DropTable @CatalogNode
    DropTable @Document

Look at the pretty sigils.

author: Nathan Stott | posted @ Thursday, July 10, 2008 8:57 PM | Feedback (2)

Get Involved in Mite


Hi community.

Mite is looking for contributors.  We need coders, testers, documenters, evangelists, and most of all users!

Check out the projects home on google code here: http://code.google.com/p/mite-net/

If you're interested in using Mite in your own project, let me know.  I'll do everything I can to help you get started with it.

If you need to contact me, leave a comment on this blog or use the contact from on the menu on the left.

author: Nathan Stott | posted @ Wednesday, July 09, 2008 11:40 AM | Feedback (1)

Migration DSL Part 1


This is the first of a multi part series of posts on the creation of the Mite Migrations DSL.

In this post I will show you how to write a non-trivial transformer that truly customizes our Domain Specific Language so that we're not using POBoo (Plain Old Boo).

Syntax Matters

A fundamental principle of DSLs is that syntax matters.  A friendly syntax makes a language easier to read, easier to understand, and makes programmers more productive.  We are not slaves to the machines.  The machines are slaves to us!  They should understand a simple syntax that humans are comfortable with.

Now that we've established that, let's get started shall we?

Download the sample project to follow along.

Desired CreateTable Syntax

This is the syntax that I am going for:
CreateTable "Cats":
    Int32 "Id", { "identity" : true, "primary" : true }
    String "Name", { "length" : 50 }


Int32 and String are constructors for subtypes of Column.  Don't worry about that now, I'll define it later for you.

Also, since this is a language and not XML configuration, we should be able to define and use methods and variables in our DSL script.  The following should work:


tableName = "Cats"

getKey = do(name, dataType):
    return Column name, dataType, { "primary" : true }

CreateTable tableName:
    getKey "Id", DbType.Int32


I know that I haven't explained everything that's going on here yet, but bear with me.  I'm just demonstrating the type of syntax that I want to create.

Also, this is a first draft of the syntax.  Eventually the need for strings will be alleviated via the use of sigils.

Boo Basics

In Boo, a method may be invoked without parameters.  Therefore  Int32 "Id", { "identity" : true, "primary" : true } and     Int32("Id", { "identity" : true, "primary" : true }) are equivalent.  Leaving the parenthesis out of a method call makes code much more human readable.

The { "something": somevalue } statements are hashes.  Boo.Lang.Hash is based on Hashtable from the .NET framework.

In Boo, constructors are called without the new operator.  For a class called Int32, calling Int32(...) is a call to the constructor.

Rhino DSL

As in my last posting, I will again be using Rhino DSL to help customize the Boo compiler.

Note: Since my last posting, AnonymousBaseClassCompilerStep has been renamed ImplicitBaseClassCompilerStep.

Implicit Base Class

The foundation of DSL creation with Rhino DSL is to define a base class with a method (or methods, but we'll talk about this later) in which to insert the DSL code.  The DSL code will then be able to implicitly call the base class methods.  Thus, the base class methods provide the API for the DSL.

public abstract class MigrationBase
{
protected void CreateTable(params Column[] columns)
{
...
}

public abstract void Run();
}

The DSL script will be loaded into the abstract Run method of MigrationBase and the CreateTable call in the example will actually call the CreateTable method on MigrationBase.  This is a simple yet extremely powerful concept. 

For completeness sake, here is the Column class

public class Column
{
public Column(string name, DbType dataType, Hash options)
{
Name = name;
DataType = dataType;
if (options.ContainsKey("primary"))
Primary = (bool)options["primary"];
if (options.ContainsKey("identity"))
Identity = (bool) options["identity"];
if (options.ContainsKey("length"))
Length = (int) options["length"];
}

public string Name { get; set; }
public bool Primary { get; set; }
public bool Identity { get; set; }
public int Length { get; set; }
public DbType DataType { get; set; }

public override string ToString()
{
return Name;
}
}

public class Int32: Column
{
public Int32(string name): base(name, DbType.Int32, new Hash())
{
}

public Int32(string name, Hash options) : base(name, DbType.Int32, options)
{
}
}

public class String: Column
{
public String(string name, Hash options) : base(name, DbType.String, options)
{
}
}

Transformers

The Boo compiler is extensible.  This is what makes it perfect for writing DSLs.  The Boo compiler allows you to interact with the Pipeline.  There are 46, last I checked, compiler steps in the regular Boo Compiler Pipeline.  The Pipeline consists of compiler steps.  A compiler step can interact with the parsed code and change the abstract syntax tree.

We will customize the compiler pipeline by adding two steps.  The first step we will add will be the ImplicitBaseClassCompilerStep from Rhino DSL.

The second will be the compiler step that runs the transformer that will turn the block in our sample DSL CreateTable code into arguments.  I'll show you how to make the transformer and the compiler step in just a moment.  Before that, lets talk about blocks.

Blocks

In Boo, when you see an indented section of code after a line ending in a colon, the indented section is a block.  Therefore, in this code:

CreateTable "Cats":
    Int32 "Id", { "identity" : true, "primary" : true }

The Int32 constructor call is inside of a block.  Now look at the definition of CreateTable on our MigrationBase.  It expects the columns to be passed as arguments.  A block is not the same as arguments.  Therefore, we need to translate the abstract syntax tree of the boo program to match what we want.

Before the ExpandMacros compiler step, we need to perform this translation.  Why the ExpandMacros compiler step?

Macros

When the Boo compiler encounters an unknown keyword, it treats it as a macro.  I highly suggest reading up on macros.

A boo MacroStatement takes arguments and a block.  The syntax is as follows:

SomeMacro arg1, arg2, ...:
    block

DepthFirstTransformer

We will write a transformer to walk the abstract syntax tree (AST) turning the statements inside of the block into arguments to the macro.  Boo provides a helpful class to override to make this easier: DepthFirstTransFormer.

DepthFirstTransformer walks an AST calling a method each time a node is encountered.  You can inherit from DepthFirstTransformer and override the appropriate methods to add your own handling for those nodes.  In this case, we need to deal with macro blocks, so we will override the OnMacroStatement method.

Here is the overridden method:
public override void OnMacroStatement(MacroStatement node)
{
if (methods.Contains(node.Name))
{
if (node.Block != null)
{
var expressions = TransformBlock(node.Block);
foreach (var expression in expressions)
node.Arguments.Add(expression);
node.Block = null;
}
}
base.OnMacroStatement(node);
}
TransformBlock takes a block and returns Expression[].   These expressions are then added as the arguments to the macros argument list.

The variable methods in the if statement is a string array that contains the names of the methods that we wish to transform.  In this case, we will be passing in only "CreateTable".  It is defined in the ctor.

private string[] methods;

/// <summary>
/// Creates an instance of BlockToParametersTransformer.

/// </summary>

/// <param name="methods">Names of the methods whose
/// invocations should have blocks changed to arguments.
/// </param>

public BlockToParametersTransformer(params string[] methods)
{
this.methods = methods;
}

Now for the interesting part, the TransformBlock method.

private static Expression[] TransformBlock(Block block)
{
var expressions = new List<Expression>(block.Statements.Count);
foreach (Statement statement in block.Statements)
{
if (statement is ExpressionStatement)
{
expressions.Add((statement as ExpressionStatement).Expression);
}
else if (statement is MacroStatement)
{
var macroStatement = statement as MacroStatement;
if (macroStatement.Arguments.Count == 0 && (!macroStatement.Block.HasStatements))
{
// Assume it is a reference expression
var refExp = new ReferenceExpression(macroStatement.LexicalInfo);
refExp.Name = macroStatement.Name;
expressions.Add(refExp);
}
else
{
// Assume it is a MethodInvocation

var mie = new MethodInvocationExpression(macroStatement.LexicalInfo);
mie.Target =
new ReferenceExpression(macroStatement.LexicalInfo, macroStatement.Name);
mie.Arguments = macroStatement.Arguments;

if (macroStatement.Block.HasStatements)
{
// If the macro statement has a block,
// transform it into a block expression and pass that as the last argument
// to the method invocation.
  var be = new BlockExpression(macroStatement.LexicalInfo);
be.Body = macroStatement.Block.CloneNode();

mie.Arguments.Add(be);
}

expressions.Add(mie);
}
}
else
{
throw new InvalidOperationException(
string.Format("Can not transform block with {0} into argument.",
statement.GetType()));
}
}
return expressions.ToArray();
}

A lot is going on in this method, so lets tackle it piece by piece.

if (statement is ExpressionStatement)
{
expressions.Add((statement as ExpressionStatement).Expression);
}

This is the trivial case.  If we encounter an expression statement, then we just take the expression and add it to the list of expressions to return.

Next we check to see if we have a MacroStatement.

If we do, then we have to see if it has any arguments or a block.

var macroStatement = statement as MacroStatement;
if (macroStatement.Arguments.Count == 0 && (!macroStatement.Block.HasStatements))
{
// Assume it is a reference expression var refExp = new ReferenceExpression(macroStatement.LexicalInfo);
refExp.Name = macroStatement.Name;
expressions.Add(refExp);
}

If it has no arguments and no block, we assume that this is a ReferenceExpression that has not been bound yet.  We transform it into a reference expression and add that to our list of expressions to return.  This is a very important step, otherwise local variables declared inside of the DSL script would not be usable inside of our block!  I suggest that when you download the sample project, you experiment without this clause and try to use the DSL and see what happens.

Ok, so if it has arguments or a block, this macro statement must be intended to be a method call.  Therefore we do this transformation:
else {     
// Assume it is a MethodInvocation
var mie = new MethodInvocationExpression(macroStatement.LexicalInfo);
mie.Target =
new ReferenceExpression(macroStatement.LexicalInfo, macroStatement.Name);
mie.Arguments = macroStatement.Arguments;

if (macroStatement.Block.HasStatements)
{
// If the macro statement has a block,
// transform it into a block expression and pass that as the last argument

// to the method invocation.

var be = new BlockExpression(macroStatement.LexicalInfo);
be.Body = macroStatement.Block.CloneNode();

mie.Arguments.Add(be);
}

expressions.Add(mie);
}

If we have encountered something that is neither an Expression nor a MacroStatement, there's nothing we can logically do with it so we throw an InvalidOperationException.

Plumbing

public class MiteEngine: DslEngine
{
public MiteEngine()
{
Storage = new FileSystemDslEngineStorage();
}

protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
{
compiler.Parameters.Ducky = true;
pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof(MigrationBase), "Run", "BlockToParameters"));
pipeline.InsertBefore(typeof(ExpandMacros), new BlockToParametersCompilerStep());
}
}

class Program
{
public static void Main(string[] args)
{
DslFactory factory = new DslFactory();
factory.Register<MigrationBase>(new MiteEngine());
var bc = factory.Create<MigrationBase>("test.boo");
bc.Run();
Console.ReadLine();
}
}
Test.boo

someVariable = Int32("Age")

someMethod = def(x as Column):
    return x

someMethodWithABlock = def(x as ICallable):
    return x()

CreateTable:
    Int32 "Id", { "primary" : true, "identity" : true }
    someVariable
    someMethod String("name", { "length" : 55 })
    someMethodWithABlock:
        return String("nickname", { "length" : 55 })


Hook up something to show that the transformation is working inside of CreateTable on MigrationBase:

protected void CreateTable(params Column[] columns)
{
foreach (Column column in columns)
Console.WriteLine(column);
}

Now try it out and see the results:

Id
Age
name
nickname

Yay, success.

Next time, we'll make it actually create the table in a database!

Here's the sample project.

If you have any questions or comments, don't hesitate to post them. 

author: Nathan Stott | posted @ Saturday, July 05, 2008 1:35 PM | Feedback (0)