Archive

Archive for April, 2009

.NET Generic Function : Func & Action where have you been in my life?

April 26th, 2009

[download example project]

Screen cast @ http://dimecasts.net/Casts/CastDetails/105

Just discovered the generic delegate type in .NET that I’ve been building over and over again. (sigh) [ Don’t forget Action<T> – works the same way but returns VOID ]

Problem:

A generic function is needed to define an event handler or implement strategy pattern. Also, in the case of an event, I want to avoid sending the calling object or EventArgs<T>.

Solution:

Previously I built my own delegate.

// the wheel I re-invented

public delegate int delStrategy(int a, int b);

public class OldWay
    {
        public delStrategy Strategy { get; set; }

When I should have just used the generic function built into  the language.

public class NewWay
{

    // generic function is the wheel
    // that I re-invented over and over again (ugh)
    public Func<int, int, int> Strategy { get; set; }

Use:

// OLD WAY

OldWay oldWay = new OldWay();
oldWay.Strategy = delegate(int a, int b) { return a + b; };
Console.WriteLine("Old Way Result: " + oldWay.DoYourThing(1, 2));

// NEW WAY

NewWay newWay = new NewWay();
newWay.Strategy = delegate(int a, int b) { return a + b; };
Console.WriteLine("New Way Result: " + newWay.DoYourThing(1, 2));

// New New Way (More terse)

newWay.Strategy = (int a, int b) => return a+b;

 

The generic function / delegate has 5 overloads:

Func<TResult>

Func<String> myFoo = delegate(){ return “Foo”; }

Func<T1, TResult>

Func<String, String> myFoo2 = delegate(String st){ return st; }

Func<T1, T2, TResult>

Func<String, String, int> myFoo3 = delegate(String st, int a) { return st + a; }

Func<T1, T2, T3, TResult>

Func<String, String, int, bool> myFoo4 = delegate(String st, int a, bool b){…}

Func<T1, T2, T3, T4, TResult>

Func<String, String, int, bool, int> myFoo4 = delegate(String st, int a, bool b, int c){…}

alan.huffman C# , , , ,

Anemic Domain Model Anti-Pattern

April 24th, 2009

We have built a brown field project, which is to say that it has some ugly architectural and coding attributes.

There are 2 mains issues with it.

  1. Low code coverage (unit tests)
  2. In many cases we implemented the Anemic Domain Model Anti-Pattern (see Fowler’s blog)

The issue, in part, is that LINQ psychologically pushed us in that direction (I think – or maybe I’m just making excuses).

This is an example, but we mapped out an architecture a few years ago that was along the lines of this simple tiered structure:

 image

** Note the use of “tbl” for tables & Entity objects is merely to reinforce their connection to the DB due to the 1 table –> 1 object mapping of LINQ. (I don’t use “tbl” in my tables)

All seemed well in the world. We happily went on our way creating partial classes for our tables.

First User Story: Determine the Order cost.

The solution seemed easy enough, loop through the order lines, add up each order line cost, and take the sum.

public Currency Cost( ){

    return this.tblOrderLines.Sum( ol => ol.Cost );

}

But then came the question of where to put this. Obviously OOP would push us to put .Cost() on the tblOrder object. But we faced two problems:

1) By naming the persistence layer as DAL Layer, psychologically we were averse to putting too much business logic there.

Perhaps the DAL layer *is* the Domain Object layer and by merely renaming the DAL Layer as Domain Layer, we would have felt better about it.

2) The second was that the tblOrder object didn’t have enough information to determine the total cost of the order. We had to add taxes, and the amount of taxes changed depending on the state and the type of the order_line.

The Order really needed access to DataContext in order to grab additional information from a tblTaxState table. This is were we made the mistake of putting the COST() into the OrderService

public Currency Cost(tblOrder ord, DBcontext db){

       tblTaxState st = db.tblTaxStates.Where(

                                 txSt => txSt.State == ord.Patient.State

                               ).First();

       Currency cost = new Currency();

        ForEach( var ol in ord.tblOrderLines ){

                    cost += ol.Cost + txSt.ApplyTax( ol );

        }

       return cost;

}

There are a number of ways we could have better solved this. We could have passed the tblTaxState to the tblOrder.Cost() method.

  tblTaxState st = db.tblTaxStates.Where(

                                 txSt => txSt.State == ord.Patient.State

                               ).First();

Currency cost = ord.Cost( st);

Or perhaps even better, would have been to merely pass the DBContext to the tblOrder.Cost() method

Currency cost = ord.Cost(db);

My question is whether that passing around of the DB Context to Domain / Entity objects *SMELLS*.

alan.huffman Architecture, Uncategorized , , ,

Modified Closures should be a language bug

April 19th, 2009

Summary:

When you define a closure within the context of a loop, the closure is defined with the final value of anything iterated over in the loop. If this sounds strange, that’s because it is. See the simple example below.

The Code:

Download: [C# File] [Zipped Console Project]

image

The curious part is the simple PrintMe delegate that takes no arguments & returns nothing.

delegate void PrintMe();

Within the foreach loop where we iterate over the int array {1,2,3,4}, we define a closure (delegate) that merely prints i the integer being iterated.

(PrintMe)delegate(){    Console.WriteLine(i);   }

The Output:

You might expect the output, when we invoke each PrintMe delegate to be 1, 2, 3 & 4, but instead the output is 4, 4, 4, 4.

image

Solution:

By copying the value of i to a local variable j and the expected result is the actual result. We iterate over the integer array { 1,2,3,4 } and we print { 1,2,3,4 }.

This one line is the strange fix.

int j = i;

Just use j in the closure instead of i

(PrintMe)delegate()
         {
             Console.WriteLine(j);
         }

Download: [C# File] [Zipped Console Project]

image

image

alan.huffman C#, Modified Closures , , , ,

Building a distributed workflow

April 15th, 2009

Summary:

My company required a data driven Work Flow that was generic enough to handle all long running and synchronous business processes. Since I built most of this at home ( I never have time to actually develop projects at work ), I feel liberated to blog about my experience.

High level business requirements were:

  • Generic
  • External to all applications
  • Data Driven
  • Quick / Easy manipulation of business rules

High level Technical requirements:

  • Fast / easy development of workflows
  • Abstracted Data Schema / Model
  • Distributed work flow using web services (WCF)
  • Asynchronous transitions
  • Enterprise Scalable

Here is an example work flow I used: 
  image

Before going into the details of the Work Flow, let me outline the

Development environment:

  • Language: C#
  • Application Platforms: Services, Winforms, WPF
  • OS: Windows Server 2003, 2008 & XP
  • DB: SqlServer 2005
  • ORM: LINQ To SQL (DLINQ)
  • WebService Technology: WCF [ HTTPBasicBinding & NETTCPBinding -- though can support any WCF binding protocol]
  • Visual Studio 2008 SP1 w/ Resharper 4.1
  • Source Control: SVN w/ Tortoise SVN
  • Build Server: Team City
  • Unit Testing: NUnit & RhinoMocks
  •  
    Aside (DLINQ/LINQ To SQL Concern)
    One of my concerns was that LINQ to SQL (DLINQ) would go away [ be deprecated ] in lieu of ETF (Entity Frame Work). I would have used ETF, but LINQ is so simple and has lazy loading — ETF has an unsavory way of doing this. I’ll move to ETF in the future, but for now DLINQ rocks.
         So to decrease the risk of DLINQ going away, I used a strategy
    Bryan Hunter from FireFlyLogic.com introduced me to. Essentially slipping interfaces in front of the LINQ Datacontext and, in my case, exposing my EntitySets as IQueryable<Entity> lists off of a repository pattern. (I’ll try to post this idea as “Unit Of Work”)

Basic / High Level Architecture:

The workflow is to be used across the enterprise and load would grow in time. So it had to scale up. To support this the participating components of the Workflow had to be able to run in parallel. There are three main components to the workflow:

1) Workflow Servers : Responsible for transitioning from tasks.

2) API’s : Programming interfaces for external clients / applications to interact with.

Our company has a legacy Access/ADP system that is widely used. In order to allow this system to consume / use the workflow, a database/stored procedure API was created along side the WCF/WS API.

3) Resources : These will be discussed later, but are the building blocks of all custom workflows. They are exposed over Web Services.image

Brief Definition of a workflow

Workflows definitions can be complicated, but here the most basic unit of work is a Work Item which is the intersection of three things:

  1. Case: The item / entity being worked on. (ex: A Customer)
  2. Task: The action to be done (ex: Make a sales call)
  3. Resource: The thing/entity doing the work (ex: Employee or the IVR (interactive voice recognition) software making the call.)

image

A work item is the intersection of these three items (ex: The IVR System will make a sales call the customer) or (ex: An employee will make a sales call to the customer).

Task transitions: A Task has outcomes that optionally transition to additional tasks (ex: Call customer, if they do not answer (outcome), make second call in 2 days).

image

A Workflow Definition is nothing more than tasks joined to each other via outcomes / transitions. (ex: [task] Call the customer, [outcome] if they do not answer, [task] make second call, [outcome] if customer is interested, take order [action], if customer pays [outcome], send order [action].)

image

Using Workflow occurs when work items are created based on outcomes. Not all potential tasks / work items occur (ex: if the 1st sales call is successful, the 2nd sales call never occurs)

image

Here is an example workflow that attempts to sell *something* to a customer. A sales person or IVR (resource) calls (task) the customer (case) trying to get an order. Call up to 3 times, if the customer can not be contacted, send them a mailer. If the customer is interested, take the order and upon payment, send the order.

image

Let’s do some code!

Simplicity was the key to design. All consuming programmers (those building workflows) should have to develop as little as possible. The framework should take care of the complexity. So what does must be built?

Workflows are built of tasks, but resources are the programming behind the task. A resource is constituted of 3 interfaces:

  • ICreateWorkItem – (optional) creates the work item given a case.
  • IValidateTransitionToWorkflowItem – (optional) validates that the case can be transitioned to this task & create subsequent workitem.
  • IDoWorkItem — (required) responsible for doing the task/action.

These interfaces had to be simple, so they are:

[ServiceContract(Namespace="http://workflow/2008/03")]
public interface ICreateWorkItem
{
    [OperationContract]
    WorkItemData CreateWorkItem(WorkItemData wd);
}

[ServiceContract(Namespace = "http://workflow/2008/03")]
public interface IValidateTransitionToWorkItem
{
    [OperationContract]
    ValidateResultData Validate(List<CaseData> cases);
}

[ServiceContract(Namespace = "http://workflow/2008/03")]
public interface IDoWorkItem
{
    [OperationContract]
    WorkItemData Do(WorkItemData wi);
}

What is required to actually define a task? As with many Domain Specific Languages (DSL), I chose XML. Here is an example of a task definition.

<!– ######################### –>
<!– ## 1st Sales Call ####### –>
<!– ######################### –>
<TaskNodeDefinition >
    <Statuses>
        <Status IsInitial="True" Name="NotCon" Desc="Not Contacted" />
        <Status Name="NoAns" Desc="No Answer" >
            <Task Name="2ndCall" Validation="False">
                <DueDate Type="delay" increment="days">2</DueDate>
            </Task>
        </Status>
        <Status Name="Yes" Desc="Yes, purchase." >
            <Task Name="TakeOrder" >
                <DueDate Type="now"/>
            </Task>
        </Status>
    </Statuses>
</TaskNodeDefinition>

And that is all it takes. Define each task w/ the appropriate XML and implement necessary interfaces, and a workflow is only a few steps away. The framework deals with persistence, transitions,  scaling and reporting.

alan.huffman Workflow and Business Rules , , , , ,