Tuesday, February 16, 2010

Fluent interface for hierarchical structures

Fluent interface works well in combination with builder pattern for representation of flat structures. But API gets a bit messy when you need represent some sort of hierarchical structure.

Currently I have “VeryVeryComplex” legacy entity and I need to represent it’s traversal algorithm in a friendly way. That looks easy when there is no arrays in the entity but as soon as it appears the code gets messy. The gist is to couple with hierarchy with a sort of collecting parameter pattern.

TouchEach method has 2 parameters: the collection to enumerate and “touch” delegate, that will be applied to each item in the collection. The delegate itself has also 2 arguments: t - toucher instance, that acts as a collecting parameter and i – collection element.

The consumer code would look like this:

var t = new Toucher();
var c = new VeryVeryComplexEntity();
t.Touch(c)
.Touch(c.Child1)
.Touch(c.Child2)
.TouchEach(c.SubCollection1
(t, i) => {
t.Touch(i.SubSubChild1)
.Touch(i.SubSubChild2);
// The same for Subcollection of i - item
});

Naive toucher implementation:


class Toucher
{
List<object> _items = new List<object>();
public Toucher Touch(object obj)
{
_items.Add(obj);
return this;
}
public Toucher TouchEach<T>(IEnumerable<T> collection, Action<Toucher, T> subTouch)
{
foreach(var i in collection)
{
subTouch(i, this);
}
return this;
}
}

Happy coding :).

Sunday, February 7, 2010

Handle incoming protobuf messages with IIS Server.

The task is to receive protobuf messages that is sent from client via IIS Server. Of course, you can use native protobuf server to handle incoming request. In my case rest of the application is written using IIS, so I don’t want to cope with additional server process.

Client will send HTTP POST request with content that is protobuf encoded message. IHttpHandler on the other side will be listening for this message on the other side.

To do this, you need to modify web.config:

<configuration>
<httpHandlers>
<add verb="*" path="Device.proto.aspx" validate="false" type="Server.ProtoHttpHandler, Server" />
</httpHandlers>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<system.webServer>
<handlers>
<add name="ProtoHttpHandler" path="Device.proto" verb="*" type="Server.PrototHttpHandler, Server" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>

This will invoke ProtoHttpHandler that can handle incoming message.

public class ProtoHttpHandler : IHttpHandler
{
private UnityContainer _Container;

public ProtoHttpHandler()
{
_Container = new UnityContainer();
}

public void ProcessRequest(HttpContext context)
{
var handler = _Container.Resolve<RequestHandler>();
var decoder = _Container.Resolve<ProtobufEncoder>();
var messages = decoder.Decode(new BinaryReader(context.Request.InputStream).ReadBytes(context.Request.ContentLength));

foreach (var deviceMeasureRequest in messages)
{
handler.OnMeasreRequest(deviceMeasureRequest);
}
context.Response.End();

}

public bool IsReusable
{
get { return true; }
}
}

Thursday, February 4, 2010

How to handle ASP.NET Update Panel in WatiN

Handling asp.net update panels with WatiN is a pretty annoying thing.
Click and WaitForLoad usually throws timeout every time.

I have found "just fine" solution that work for me:

static class ElementExtension
{
public static void ActWithToken(this Element Element, Action Action)
{
string Waittoken = "waittoken";
Element.SetAttributeValue(Waittoken, Waittoken);
Action();
Element.WaitUntil(!Find.By(Waittoken, Waittoken));
}

public static void ActWithToken<E>(this E Element, Action<E> Action)
where E : Element
{
string Waittoken = "waittoken";
Element.SetAttributeValue(Waittoken, Waittoken);
Action(Element);
Element.WaitUntil(!Find.By(Waittoken, Waittoken));
}
}


Usage



Page.CreditToLocation.FindItem(1).ActWithToken(e => e.ClickNoWait());

Wednesday, February 3, 2010

Call stored procedure with output parameter using Builder pattern

My custom DAL requirements is:
  1. By given Business objects (BOs) call stored procedures
  2. Handle output parameters (updating BOs fields)
  3. Throw exceptions, if error code returned from stored procedure
Coding this functionality using ADO.NET is a bit annoying. The majority of code consists of communication with framework interface, and does not explicitly express developer's intensions. Example.
Such annoying code can be refactored nicely using Builder pattern. Target interface for me is interface like this:
public void Update(ObjectContext Ctx, BusinessObject Row)
{
CommandBuilder Builder = InsertOrUpdateBuilder(Ctx, "updateBusinessObject", Row);
Builder.ErrorCodes
.Parameter("err_code_out")
.Handle<ConcurrencyException>(-1);

Builder
.Parameter("id", Row.Id)
.Parameter("last_update_date", Row.LastUpdateDate)
.Parameter("last_updated_by", Row.LastUpdatedBy)
.Output<DateTime>("last_update_date_out", (d) => Row.LastUpdateDate = d)
.Create()
.ExecuteUpdate();
}

public void Insert(ObjectContext Ctx, BusinessObject Row)
{
InsertOrUpdateBuilder(Ctx, "insertBusinessObject", Row)
.Parameter("created_by", Row.CreatedBy)
.Output<int>("id_out", (Id) => Row.Id = Id)
.Create()
.ExecuteUpdate();
}

This interface is versatile enough to express required stored procedures call scenarios and explicit enough to be readable by human.

Literally Update call do this:

  1. If Stored procedure returns –1 from parameter "err_code_out", Concurrency exception will be thrown.
  2. Parameters "id", "last_update_date" and "last_updated_by" will be added to stored procedures
  3. Parameter "last_update_date_out" will be threaded as output parameter of type DateTime and mapped to Row.LastUpdateDate.

Implementation

The idea of Builder pattern, is to hide complex construction logic behind clear and explicit API.
Builder responsibility is to collect consumer "wishes" and return something that consumer can execute, to make "wishes" come true.

Here is builder implementation:

public class CommandBuilder
{
private readonly DbCommand _Command;
private readonly OutputParameterMapper _ParameterMapper = new OutputParameterMapper();
private readonly ErrorCodeHandler _ErrorCodeHandler;

public CommandBuilder(ObjectContext Ctx, string Name)
{
_ErrorCodeHandler = new ErrorCodeHandler(Name);
_Command = Ctx.CreateStoreCommand(
Name,
CommandType.StoredProcedure);
}

public IErrorCodeHandlerBuilder ErrorCodes
{
get
{
return _ErrorCodeHandler;
}
}

public CommandBuilder Parameter(string Name, object Value)
{
if (Value == null)
{
Value = DBNull.Value;
}

_Command.Parameters.Add(new SqlParameter(Name, Value));
return this;
}

public CommandBuilder AddPagingParameters(PageSortInfo PageSortInfo)
{
_Command.AddPagingParameters(PageSortInfo);
return this;
}

public CommandExecutor Create()
{
if (_ErrorCodeHandler.ParameterName != null)
{
Output>int<(_ErrorCodeHandler.ParameterName, (ErrorCode) => { _ErrorCodeHandler.ThrowOnError(ErrorCode); });
}

return new CommandExecutor(
_Command,
_ParameterMapper);
}

public CommandBuilder Output>T<(string ParameterName, Action>T< Func)
{
var Parameter = new SqlParameter(ParameterName, default(T));
Parameter.Direction = ParameterDirection.Output;

_Command.Parameters.Add(Parameter);
_ParameterMapper.AddMap(ParameterName, Func);
return this;
}
}

After class consumer calls create on Builder, it returns Command executor. Command executor is already configured to execute desired stored procedures with parameters and map output parameters after execution.

I have cheated a bit with ErrorCodeHandler, it is a builder and an executor in the same time (say hello to SRP), but it doesn't causes much damage for now. The execution interface is hidden by IErrorCodeHandlerBuilder.


public class ErrorCodeHandler : IErrorCodeHandlerBuilder
{
private readonly IDictionary>int,type< _ErrorsDictionary = new Dictionary>int,type<();

private readonly string _ProcedureName;
private string _ParameterName;

public string ParameterName
{
get
{
return _ParameterName;
}
}

public ErrorCodeHandler(string ProcedureName)
{
_ProcedureName = ProcedureName;
}

public IErrorCodeHandlerBuilder Handle(int ErrorCode, Type Exception)
{
_ErrorsDictionary.Add(ErrorCode, Exception);
return this;
}

public IErrorCodeHandlerBuilder Handle<T>(int ErrorCode)
{
_ErrorsDictionary.Add(ErrorCode, typeof(T));
return this;
}

public IErrorCodeHandlerBuilder Parameter(string Name)
{
_ParameterName = Name;
return this;
}

public void ThrowOnError(int ErrorCode)
{
Type ExceptionType;
if (_ErrorsDictionary.TryGetValue(ErrorCode, out ExceptionType))
{
var Exception = (Exception)Activator.CreateInstance(
ExceptionType,
String.Format("Stored procedure {0} returned error code {1}", _ProcedureName, ErrorCode));
throw Exception;
}
}
}

The output parameter mapper is a bit tricky. It introduces 2 classes Map<T> and Map to bypass C# generic typing systems, and make polymorphism to work.

public class OutputParameterMapper
{
private readonly List<IMap> _Map = new List<IMap>();
private interface IMap
{
string ParameterName { get; set; }
void InvokeSetter(object Value);
}
public void AddMap<T>(string ParameterName, Action<T> Setter)
{
_Map.Add(new Map<T>()
{
ParameterName = ParameterName,
Setter = Setter
});
}

public void MapParameters(DbParameterCollection Parameters)
{
foreach (var Map in _Map)
{
var Value = Parameters[Map.ParameterName].Value;
Map.InvokeSetter(Value);
}
}
private class Map<T> : IMap
{
public Action<T> Setter { get; set; }
public string ParameterName { get; set; }
public void InvokeSetter(object Value)
{
Setter((T)Value);
}
}
}

Command executor class, when called blows all that stuff (triggers exception throwing and parameters mapping)


public class CommandExecutor
{
private readonly DbCommand _Command;
private readonly OutputParameterMapper _Mapper;
private readonly ErrorCodeHandler _ErrorHandler;

public CommandExecutor(DbCommand Command, OutputParameterMapper Mapper)
{
_Command = Command;
_Mapper = Mapper;
}

public DbCommand Command
{
get
{
return _Command;
}
}

public void ExecuteUpdate()
{
using (_Command.Connection.CreateConnectionScope())
{
_Command.ExecuteNonQuery();
_Mapper.MapParameters(_Command.Parameters);
}
}

public T ExecuteScalar<T>()
{
using (_Command.Connection.CreateConnectionScope())
{
var Scalar = (T)_Command.ExecuteScalar();
_Mapper.MapParameters(_Command.Parameters);
return Scalar;
}
}
}


The idea of builder pattern was given to me by my colleague, thanks. :)

kick it on DotNetKicks.com