Friday, August 29, 2008

Build Tools

The number of available build tools in .Net grows daily it seems... and i feel i am falling behind.
MSBuild and NAnt are the standards in the .Net world but the uprising of Ruby has formed Rake, which is also usable in .Net. Rake is a Ruby implementation of the build tool Make which has inspired the .Net equivalent Boobs Bake from Ayende and now James Kovacs has PSake (pronounced sake as in the Japanese wine)....
I really will have to look into these... jeez i still haven't played with Power shell and my Ruby and Boo skills have a lot to be desired!

Thursday, August 28, 2008

The satisfaction of refactoring

I am in the process of heavily re factoring our service facade (ie WCF) layer. the first file i got hold over i have already removed 60% of the LOC and got a significant number of the methods to one line
eg:
public GeoLocationFindByIdResponse GeoLocationFindById(GeoLocationFindByIdRequest aTransportObject)
{

return FindEntityById
<IGeoLocation>(aTransportObject.Payload,this.Domain.GeoLocationFindById);
}


that's a big improvement from the 36 liner that it replaces and a whole lot easier to read.
One of our major issues was cut and paste code of logging and auditing/instrumentation. As we are not using AOP I have decided to go with passing delegates. It has actually sped up the method calls too as i have re factored out redundant methods calls and repeated logging. Now all of fault handling and the "aspect" like stuff can be handled in one place and the code is a whole lot easier to maintain.

Cool, i am happy with that!

Setting up a Greenfields project

My last post talked about technical investment. well like financial investment, its usually better to invest early.

Lee recently posted about Standards and Success Criteria. I think this is crucial for project success and hopefully this post is a concrete example of what I think are standards when beginning a project.

Setting up your solution well early can make life a lot easier. Some of the main concerns to me when initially setting up are as follows:

Naming
Establish a naming convention early on. It does not really matter what that convention is, just define it. There are some .Net guideline already established, use these if you don't already have one (iDesigns coding standard is pretty good starting place).
Be sure to talk to other developers and stake holders about the names you use and change them as needed. It will much easier to change these names early one than it will later on when multiple Dev's are in the mix and releases are already being made.
Use the correct names for commonly know things. One of the key areas I often see is pattern names used incorrectly. Make sure you understand what the pattern is if you are going to use the terms. Every self respecting developer should have GoF (or at least read it).

Libraries & tools
Define what Core and 3rd party libraries and frameworks you are going to use at the start of the project. If you are going to use .Net 3.5 and WCF use it from the beginning and use it properly.
Libries you need to consider include: Test/Mock libraries, Persistances/ORM, communication/ESB, UI, Logging, Framework (IoC, AOP etc) etc.
Tools include: Soruce control, analysis tools, code gen, IDE, CI, build, test runners/coverage, IDE plugins, documentation generators
This is also a good chance to be an early adopter. If there is a new beta release of a product you are interested in and the release is schedule for before your release, why not start using it now? Sure you will have to weigh this up yourself, however this has proved successful to me in the past.
One caveat here is make sure you know how to use the library before jumping on board. It is only after you have learnt the library that you know how steep the learning curve is. Personally I found it easier to learn a whole new language (Python) than picking up an ORM (NHibernate). Don't drag your team through hell because you wanted to play with the latest toy.

Build process
Establish a build process early on. Set you team up for success. You may not have CI set up yet but that does not mean you cant have the solution ready to go. Have your build scripts set up before you have any significant code base. Use the build script.
Ensure the build script is doing everything is should, you should not have to move dll's or copy config files etc. It should do it all.

Project Processes
Define how the project will be run from day one and do it properly. The term Agile is so flippantly thrown around, yet so rarely done properly... I find i quite annoying. To me its like saying I drive a Lexus when I am rollin' in a Toyota. There is nothing wrong with a Toyota, and it may be the best vehicle for the job, just call it what it is.

Tests
Whether you are TDD or not, I assume you are writing some sort of automate-able tests, whether they are strictly unit test or otherwise. Integrate this in to your build process. As we are talking about Greenfield projects here, define your expected test coverage up front. Now this is a doable edged sword, but i think it is worth while. Also encourage your Dev to truly embrace TDD and correct UNIT testing using mocks/fakes/stubs.
On a side note, I was talking to a Java mate yesterday and apparently there is a a pug in for IntelliJ that runs your test in a back ground thread every time you build in the IDE. With the multi-processor machines we uses nowadays, why not? It got me thinking, i could pretty easily set up something like that too for my local machine.

Follow coding best practices
The first port of call in doing this is setting warnings as errors and setting the error level as high as it can go in each of your project files in the solution.
Get FXCop and use it. if there are things you don't like then document and removed the waring, but start with it.
Some will disagree with me on this, but on this subject I say F*^K 'em. Not having these on just sets up a slippery slope. I would rather deal with the issues as they come up, not retro fix.

Follow design best practices
Terms like IoC, AOP & TDD are not just cool buzz word, they are best practices there to make YOUR life easier. Using IoC make TDD easier. Using TDD encourage the use of IoC. AOP cleans up your code from so the business problem at hand is not cluttered with technical sideshow concerns.Use these, embraces these, understand these and introduces them early on into the picture. Create a pit of success.
Also be sure to use a metrics tool like NDepend to check on your solutions health. Again, dealing with issues early may help stem some nasty heads from popping up later.

Defining future Standards and Success Criteria
This is pretty broad and somewhat recursive, but there will be personally issues that you are concerned with and project specific thing that should be address early on in the picture

Technical Investment

A recent post on Technical debt on InfoQ got me thinking about technical investment.
In the age of YAGNI, ominous PM's and tight budgets, often time is not spent on investing technically in the team or the business. We build stuff as we need it and if we can reuse something we try to, but often end up hacking it to fit our new needs, if the shoe does not quite fit.
At my current place of work we are "post live" and in a situation where investing technically makes great business sense. Our project is some what of a flag ship project as the company is
A) New to .Net, coming from a Delphi background
B) New to NTier distributed development, coming from a rich client with db connection
C) Looking to move to an SOA architecture across the company to more cleanly delineate the business logic get some reuse out of the business processes.

Because of these factors there have been mistakes that have been made. The application we have built works but it is high in technical debt. It is just holding itself together, push it just a little and it will come crumbling down.
A lot of this is to do with hurried framework design and best practices ignorance. We have acknowledged our mistakes, but that is not enough. Over the next few months this application stack is to be used as the basis for other NTier development in the new and growing .Net department, we need to make sure the other teams don't copy our mistakes. We need to make it easy for them to succeed!

IMO we need to start with re factoring our core libraries, specifically Data Access, Logging and Service Boundaries. These are areas that will be needed for all of the applications in the future so why not get this stuff right.
Are we using WCF as intended?
Are we getting the most out of NHibernate?
Can we reduce the noise from our non business aspects that have leaked in to our code?

Is this Gold plating? Well, yes i guess it is and i would not recommend it normally. However given the circumstance i think the cost of not getting this rights is too great.

So how would I do it if i was in the same position tomorrow as the guys were at the start of this project? Maybe that's the next post...

Wednesday, August 27, 2008

NDepend in action

Nice post here breaking down the metrics on the latest NHibernate release

interesting results...

Domain object mapping

I have been using Nhibernate now for almost 2 years and to be honest for most of the time really missed the point of using an ORM. I think alot of this stems for the M$ influence mindset of building from the DB up. This is not necessarily a bad thing and to be honest is often a necessity if you are using an existing DB or working disparate to the DBA or owner. However as i explore the DDD world i see the benefit of build from the domain out, especially in complex domains that are not just crud operations.
Most of my time using an ORM i have just been using it as a glorified typed data set. The object would contain data in the form of properties that mapped to the structure of the table it is mapped to. This really is not using the full strength of an ORM, and to be honest if this is all you are doing then a code gen option like Net Tiers is probably a much better path (faster, less stress easier).
However now I feel the ORM really is a way of abstracting your domain from your persistence mechanism. Unfortunately it took an nasty database to show me the light.
I dont mind admitting my mistakes, usually its in a less public forum, however these are mistake I see frequently that i dont know if the authors are aware they are making.
So here's some guidelines that i am now trying to follow, take them for what they are.

Properties != Columns
Column and property names do not need to be the same. I have often seen the suffix "Flag" for Boolean columns; however this is less IMO readable than the “Is” prefix in managed code. do not feel the need to map names directly. use the most suitable domain representation

Incorrect Mapping of Types
I have seen properties that are of type string because the underlying table has a char(1) for Y/N flags. there is then a property that interrogate the string flag property and return a bool depending on the result... yuck. Why not use the mapping correctly
<property name="IsActive" type="YesNo" column="ACTIVE_FLAG" not-null="false" />
this also applys to numeric types and strings. There are more numeric types than int, so use the most appropriate one. if a string has a max limit on the DB of 30, enforce that in your map and in your class.

Inappropriate use of the public keyword
The public key word for some reason seems to be a default accessor. it should only be used when you w this aspect of your code.
Classes
If you have a class that is in way relevant to the outer world, do not mark it as public. Many mapping classes fall in to this category. I dont want to see Foo.FooBar[0].Bar... this show me implementation details that i dont care about and just add noise. If you need the join class but it serves no public functionality encapsulate it by providing a Bar collection property that transverses the join classes to give Foo.Bar[0]. You may want to consider if your loading strategy for this relationship is appropriate (ie not lazy) if you are using this out of session.
Bottom line is: ORMs are there to provide DB/Persistence ignorance not highlight the DB structure.
Properties
Properties that are mapped to columns may not always be publicly accessible. There may be time when if you update property A then B must be considered too. Dont make these setters public, or you give the impression that changing them freely is OK. Use a method to populate the properties so you can also encapsulate business logic associated to these.
Methods
This point follows on from the preceding point. You domain objects do not have to be buckets designed to carry data. They can and should have behaviour associated to them. Not doing so leaks your logic out of the domain and results in duplicated logic and hard-to-maintain uber services. Dont let this happen.

Fear of re factoring
It is often difficult to change a database especially in post live situations. this does not mean your domain has to reflect old/incorrect data structures. Feel free to remove mapped columns form your classes and mapping files if they no longer make sense in the domain. just because one area of development is wrong it does not mean it has to leak out to the other areas.

Light Handed Mappings
That title doesn't really makes sense, what i really mean is be heavy handed with your mappings, classes and tables. Assert your assumptions. If a column can not be null, assert that in the DB, maps and in the managed code. If you know the class a will always need reference to its collection of class B then set lazy loading to false. Ignorance is a common excuse, but its one i am trying to minimise

Redundant Repositories
A repository is generally only required for an Aggregate Root. Define your boundaries and remove redundant Repositories. Do you really need an ICustomerAddressRepository? get rid of it!

Confusing the purpose of a Repository
This may be more than a ORM issue but a design issue. A Repository is a store for entities. It does not do reporting. It does not do complex SQL searches that return weird and wonderful datasets. I "like" Greg Youngs notion* (which i initially thought was wildly over the top, but goes to prove a point) of just saving the id of aggregate root and then serialise the object graph in to the other column of the table. This database is not for reporting, its for serving the domain.
Although your approach man be a little less drastic, this highlights a point. If you cant think of your repository as an in memory store then you are not using like a repository. In fact my current thought is your should be easily be able to inject an in memory store that uses the I[Foo]Repository interface and work exactly as intend , albeit a smaller set of data (eg for testing). I may be going a bit OTT here and would like feedback.

*i hope i am not miss-quoting Greg

Hopefully that has clarified some of the errors i have done/seen repeatedly in the past. i would like to here feedback. have i yet again missed a point? am i being over the top?
lay it on :)

MassTranist 101 - What is MassTransit

After playing with MT I have noticed that there is a distinct lack of entry level documentation that may put developers that are not up to the calibre or the uber nerd* MT members. so i have offered to attempt to document or at least given some guidance to help people get into it.
So i am going to start from the very start and try to aim a t a n intermediate level .net that is comfortable with web service and distributed communication etc but may be a bit hazy of what exactly terms like SOA, ESB and Asynchronous Durable Messaging mean.. ;)

*Chris, Dru and Greg and i mean nerd in the good "I am not worthy" sense

I plan to do some basic "This is what this does" type posts too, so there is some step by step articles to get people up and running fast, but for starters here is the proposed initial doc:

The official synopsis of MassTransit, from its website is as follows:
"MassTransit is lean service bus implementation for building loosely coupled applications using the .NET framework.
The lean implementation is supported by the YAGNI principle. By focusing on a tight set of specific concerns, the touch points between Mass Transit and the application are minimized resulting in a clear and concise set of interfaces."
But what does it actually do?
Well as the brief states MassTransit is a service bus for building loosely coupled applications. Let’s break that down.
So what is a service bus and how does it aid in loose coupling? Well hopefully the follow example may help you understand:
You may have 1 or more systems/components communicating with out any real knowledge of who or what each systems/components is. For example if I what to Create a New Purchase Order for a client I may send a specific message, for example a message called "CreateNewPurchaseOrderRequest" (with the company and order details inside that message) MassTransit picks up this message and forwards on to which ever system(s) is registered to deal with that type of message. Now my sending component does not know or care which system receives and deals with that message, it has done its job of raising the purchase order.
Ideally there is another system that is ready to deal with that type of message. It is given the message from the buses queue and the service processes the data in the message; persisting, starting workflows etc. It may even send a message back to the bus, say a "CreateNewPurchaseOrderResponse", to acknowledge that, yes, the purchase order has been successfully created. The original sender of the CreateNewPurchaseOrderRequest may (or may not) be interested in this response and can subscribe to the message type and act on it accordingly.
What this does require is that the bus is alerted of who wants to receive what type of messages and also that when a message is created and ready to be sent, it is passed to the bus.

Now this scenario raises a bunch of questions
Why not use method calls/web services?
• A service bus like MassTransit allows you to send and forget. You give the bus a message and let the bus decide where to send the message. This means you do not need to know that HR is now looking after message X and the Logistic is dealing with message Y differently. You don’t care. You also don’t need references to those other systems. Changes to other systems are much less likely to affect your system.
Why the ignorance?
• What happens if the business now decides that when we raise a Purchase Order we also need to alert Logistics, Warehousing, Marketing and the original Sales department? If you where using traditional web services this means you would need to go into you code add references to those web services and make class to them from the raising application. With a service bus you raise the message and let the the bus forward the message on t the interested parties. It means the component focuses on the job it is supposed to do and not worry about departmental interactions. This concern is now that of the Bus
Why messages?
• As business and their technical solution grow, maintaining those technical solutions can become difficult. Architects have been using SOA approaches to help delineate logical service and use messages as the means of moving data around. A message in itself guides the bus to what its intended purpose is. A CreateNewPurchaseOrderRequest is quite self explanatory and very specific. Well constructed messages and services means disparate components can talk to each other, showing their intention but hiding the implementation.

Benefits of MassTransit
• Loose coupling/Recipient ignorance: Send and forget. In the same vein you can subscribe to a message type and not care where it was sent from.
• Asynchronous communication: no need to hold up connections and thread waiting for replies. You can send the request and if you are interested in the response subscribe to the message type
• Durable and reliable messaging thanks to the message queue backbone (e.g. MSMQ)
• Light weight : MassTransit.ServiceBus.dll, MassTransit.ServiceBus.MSMQ.dll & MassTransit.WindsorIntegration.dll combined are under 100KB
• .Net Type safe. You can subscribe to message based on the .net type of the message. No need to interrogate XML files or manually transform .net types to xml etc
• Castle integration: The stack is built using best practices such as IoC and is ready to integrate with the popular .net Library “Castle”
• Open Source: The source code, including unit tests and samples, are available openly.

Who would want to use MassTransit?
• A designer or developer who’s systems are predominantly in .Net realm.
• A designer or developer that wants to have a means to communicate to separate systems in a loosely coupled and possibly asynchronously manner
• A designer or developer that wants to have a reliable and durable means of communication
• A designer or developer that wants to have an easy means to set up a messaging bus!

What does this require of the developer?
• You will need a supported Messaging Implementation such as MSMQ
• You will need to base your communication on a message construct i.e. each message has a specific intent and relevant data. Passing entities is not explicit enough as it does not show intent.
• You will need to reference MassTransit and use the library accordingly! (see the samples for more info)

I hope this gives some basic back grounds as to what MassTransit is and does. Any question please email me or for technical issues go here

Tuesday, August 26, 2008

Projects measuring success..

Nice post
http://leecampbell.blogspot.com/2008/08/projects-measuring-success-and.html

Intention revealing interfaces

In the argument of "Intention revealing interfaces" vs "Reusable DTO/message" i will 99% of the time lean heavily toward the "Intention revealing interfaces" side.

I have just encountered code where i can see a (somewhat) noble intention of trying to keep the number of messages available in an assembly down to a minimum. Considering the system(s) mainly passes entities across boundaries, message are not common currency.
Unfortunately i don't think enough thought was put into the decision. Leaving the notion of passing entities around as another issue, the fact that this DTO is now being used as a request AND response object in MULTIPLE service functions means the intention of each DTO is very unclear.
There are multiple fields on the DTO that are not used by the service and there is a magical "ObjectPacket" property that is of type object (as in System.Object) that is actually quite important. The reason the property's type was left as object is because of "reuse", as the different functions do different things with that property.
OMG.
Many hours, nay days, of bug fixing could have been saved if this DTO was split in to just 4 classes, 2 response and 2 requests. These could have been generic enough for the remained of the functions and revealed, along with the service function names* the intention of the call.

Thinks of other when you names stuff (classes, components, service, methods and parameters) and think of whether re usability is actually a benefit before bundling on bonus properties to a transfer object. ;)

*yes this is a JBOS interaction

VS2008/3.5 SP1 == Fail

Ok, so its been about a week of running SP1 on vs2008 and all i can sy is: "WTF?!?" There is no need to list the bugs, as the interweb is chocka full of them (including a couple I have posted to the conect team), but I must say that I have been incredibley underwhelmed. When i install an SP i dont expect everything to break. This is the worst release i have encountered from M$ in a while. I am really dissapointed in a team that i thought was on the up and heading in a new positive direction. :(

Thursday, August 21, 2008

Rusty on the ol' SQL

It took me a good 15 minutes to figure out how to get a list of table names with schema's from sql 2005..jeez. not good.
I would not be surprised if its actually wrong. Anyway, whats with hiding the sys tables? Weird.

select ss.name 'schema', so.name 'table'
from sysobjects so
inner join sys.schemas ss
on so.uid = ss.schema_id
where so.xtype = 'U'
order by ss.name, so.name

Tuesday, August 19, 2008

Mass Refactoring of a Poor DDDD Stack

We are at a cross roads on our current project where:
• We are hitting limitation of our current architecture and framework
• We need to be able to facilitate service orientation and be come part of an SOA environment
• We are not completely swamped with work
• Bugs are lingering in a hard to understand convoluted stack

We have an NHibernate /Oracle based distributed (client - server) application.
Current concrete problems:
• We pass entities around across service boundaries. These entities can be huge and are therefore very slow to pass around and we hit upper limits on WCF message size (semi)regularly. The screens we are displaying show a lot of related data and the load time for some pages is insanely slow.
• Our application has some smarts in it that can be argued are actually domain logic, not application logic.
• We have a lot of code repetition “copy and paste mania” through out the stack
• We have a tightly coupled stack; using doubles/mocks/fakes at times is near on impossible meaning test are integrated, brittle and slow
• Services expose too many finely grained functions, many of which are not appropriate as public calls.
• We have one domain which needs to be spilt to shared kernels
• We have a very anaemic domain. Our domain objects are treated a bit like strongly types datasets with the service controlling business logic and flow.
• Poor separation of concerns both vertically and horizontally (i.e. mega classes)
• subtle and painful circular references
• Logic in views


DDD
• Clearly define boundaries. Implicit knowledge should not be required. Code should be fluent and readable. Refactoring is therefore a necessary component of building a fluent domain
• Flesh out the actual business problem and map it completely and deeply into the domain code. Reading a domain entity class it should obvious what it can do and what is cant.
• Assert your assumptions, use DBC, predicates, valuators and factories, especially with complex entity construction
• Domain entities are smart. Do not let the smarts of these domain object leak into the repositories or services (ie an anaemic domain)
• Repositories are just that, effectively a bucket holding domain objects. If you want to do complex DB logic use a report data access call, don’t muddy the repositories with reporting.
• Services are aggregators of domain functionality. They control flow and coordination between Repositories, Factories and Domain objects. They do not hold leaked domain logic.
• Reports are anything that is not domain object based: Actual reports, Scheduling, Complex db searching etc. These may return objects but they are not smart domain entities, nor are they are domain value types and so should not pollute the repositories.
• Value types are immutable and so consider whether they are suitable to be structs (e.g. time code)
• Reference Value types are read-only (i.e. only selectable form the database, never CUD) and so do not need mapped “created/last modified“ properties. These may be necessary in the DB (for standardisation) but this does not mean they need to be leaked into the domain


Distribution
• The message and service should be verbose enough to describe the functionality.
• Use messages. Don’t pass entities around across boundaries.
• Messages are immutable, don’t attempt to modify request messages on the recipient, nor should you modify response on the caller
• Feel free to reuse structures ie DTO but don’t reuse messages at all. A message is bound to a service and a function
• A message is the object passed across the wire which holds a DTO, which may be in turn made up of more DTOs. A message implements either IRequestMessage or IResponseMessage
• On entry to the server side any instrumentation/auditing/logging/security checks etc should be handling in a standardised reusable manner, consider AOP or delegate passing.
• On entry to the server side transactions/sessions should be handled as this is the entry point to the domain and a service call should be considered atomic.
• Faults, not exceptions, should be passed back to the caller.
• Consider whether the use of an ESB could improve the use of your domain. Message based communication is necessary if this is to be implemented.

Application
Logic in an application is bound to application specific flow. The exception here is validators. [I am yet to figure out how best to organise validation across boundaries. Currently my thinking is keep it very separate with well constructed messages helping]


General
Do not pollute any part of the stack with cross cutting concerns. Use AOP. The entry and exit of a method is usually more than enough context for things like security and logging. If it is not then rethink the size of your methods!
Loosely couple yours stack. Use IoC. A standard IoC container can ease testing and un-clutter the complexity of object creation.

Concerns I need to keep at the back of my mind if we switch to something like the guidelines above:
• Client and Server side Authentication and authorisation. How will we pass security tokens around?
• Concurrency, how will I address 2 user working on the same asset at the same and race conditions?

Bring on the refactoring, I just wish we did it as we went! Please learn from our lessons.

Thursday, August 14, 2008

MassTransit : Classic WebForms

The Web sample in the MassTransit download that i talked about in the last post used MonoRail. As i am working on a project not using monorail (and there may be a couple of others doing the same) i thought i would make demo project using asp.net, oldskool.

The project contains 6 files (well 9 really)
AsynchWebForm.aspx (marked as Async="true")
Global.asax
Web.config
WebAppContainer.cs
RequestMessage.cs
ResponseMessage.cs

Thats it. It references the mass transit dlls (mt.sb., mt.sb.msmq, mt.WindsorInt) and the appropriate castle dlls.
the global.asax is just like the DashboardApplication in the morails sample and the WebAppContainer.cs again is similar to the monorail sample without any references to monorail! The message are exactly the same and the web config has the castle section definition and castle section inserted into a default web.config file.
I was lazy with my resolving of the IServiceBus, see below.
-----WebApContainer--------

using System;
using Castle.Core.Resource;
using Castle.Facilities.Startable;
using Castle.MicroKernel.Registration;
using Castle.Windsor.Configuration.Interpreters;
using MassTransit.WindsorIntegration;
using MassTransit.ServiceBus;

namespace MassTransitWebTest
{
public class WebAppContainer :
DefaultMassTransitContainer
{
private static IServiceBus bus;
public WebAppContainer()
: base(new XmlInterpreter(new ConfigResource()))
{
RegisterFacilities();
bus = Resolve();
}

protected void RegisterFacilities()
{
AddFacility("startable", new StartableFacility());
}

internal static IServiceBus getBus()//yes im that lazy
{
return bus;
}
}
}


-----AsynchWebForm.aspx.cs--------

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MassTransitWebTest.Server;
using MassTransit.ServiceBus;

namespace MassTransitWebTest
{
public partial class AsynchWebForm : Page, Consumes.For
{

private IServiceBus _bus;
private Guid _correlationId;
private ServiceBusRequest _request;
private ResponseMessage msg;
private RequestMessage pendingMessage;

protected void Page_Load(object sender, EventArgs e)
{
//not much to do here
}

IAsyncResult PageBeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object state)
{
_request = _bus.Request()
.From(this)
.WithCallback(cb, state);

_request.Send(pendingMessage);
pendingMessage = null;

return _request;
}

void PageEndEventHandler(IAsyncResult ar)
{
IAsyncResult r = ar;
this.txtResponse.Text = msg.Text + " (and my response)";

}

#region All Members

public void Consume(ResponseMessage message)
{
msg = message;
_request.Complete();
}

#endregion

#region CorrelatedBy Members

public Guid CorrelationId
{
get { return _correlationId; }
}

#endregion

protected void Button1_Click(object sender, EventArgs e)
{
AddOnPreRenderCompleteAsync(
new BeginEventHandler(PageBeginEventHandler),
new EndEventHandler(PageEndEventHandler));
_bus = WebAppContainer.getBus();

pendingMessage = new RequestMessage(CorrelationId, this.txtRequest.Text);
}

}
}



Happy days! I am sure you can work out the rest, if any one cares the complete solution can be downloaded from :
http://www.fullstack.co.uk/downloads/MassTransitWebTest.zip
NB:See previous post for setting up queues

Wednesday, August 13, 2008

Mass Transit - lite weight ESB

A demo project i am frantically working on has a requirement for some sort of ESB like message control. My first instinct was to go with NServiceBus but something, for some reason drew me to MassTransit.
MassTransit is an Open source .Net project run by Chris Patterson and Dru Sellars which aims to be a "lean service bus implementation for building loosely coupled applications using the .NET framework.". Cool cause that's what I need.
It sit on top of MSMQ and has some heavy hooks into the castle project for DI etc.
I am writing this while i wait for my VS2008 SP1 install to finish... what the hell is it that thing?? oh the entity framework! well at least its worth the wait ;P

Anyway the documentation is a bit slight and i am a documentation nerd. I like to get a synopsis of what we are trying to achieve and some sample project, also documented, to help me get up to speed, so here is my very basic version of just getting started.

You can just download the binaries if you are feeling very confident or alternatively you can get the source which includes some sample projects.

Running the MassTransit samples:
NB: you will need to install/set up MSMQ (or whatever queue they support in the future), for details on how to do this, see below.
1) Download the source code to an appropriate folder using the following svn command (this is read only)
svn checkout http://masstransit.googlecode.com/svn/trunk/ masstransit-read-only

2) For Mass Transit you will need to create a private MSMQ queue of the name "test_servicebus" and leave the default setting of NOT transactional.

3) Open up the WebRequestReply.sln found in :
..\masstransit-read-only\Samples\WebRequestReply\WebRequestReply.sln (or 2008 if you have it)

4) Build the solution, ensuring it builds (I had to delete a couple of version files for both 2005 and 2008)

5) Set the monorail project to the start up project.

6) F5 that mutha.

This will show a splash screen that links to the asynch screen. Type in some stuff in the request textbox and hit the button and the response will come up.

Things to look for in the code:
The monorail project is the initiating code here and basically is the stuff you will be looking at for how to use this framework. If you are not familiar with castle, monorail and asynch calls then your head may pop.

Firstly look at the DashboardApplication.cs file. This is the gloabal.asax code behind file that is called on app start up. This file starts up the Container which loads the facilities/components using windsor IoC. The container inherits from the defaultMasstransitContainer which has Windsor Castle hooks. Check out the config to see the injection of the Uri and queue type for the bus.
In the DashboardApplication you should also see the line
container.Resolve<IServiceBus>().Subscribe<RequestMessage>(HandleRequestMessage);

and its related delegate

private static void HandleRequestMessage(IMessageContext<RequestMessage> ctx)
{
ResponseMessage response = new ResponseMessage(ctx.Message.CorrelationId, "Request: " + ctx.Message.Text);

container.Resolve<IServiceBus>().Publish(response);
}

this is saying that this delegate wants to handle the receipt of the RequestMessage, "when the RequestMessage is published i want to process it with this command".
alrighty... next is the DemoController.

This is the controller for the asych page that does the work. If you are not familiar with monorail or the ASP.net MVC project this may be a bit confusing, but this is like the code behind page for a dynamic web page. Some of the important things to note are:
Consumes<responsemessage>.For<guid>

This says that this class is interested in (consumes or subscribes to) ResponseMessages. Now i need to look more into the .For<guid> aspect so i wont comment much yet ( i assume it related to the request message id?)
The Synch method is empty but you will notice there is a BeginAsynch method with the same signature and an EndSynch method with no signatures. These methods and there contents are the asynch approach used by Monorail. Don't be too concerned, classic Asp.Net has had this little known feature for years albeit a slightly different syntax and wrapped around the pre-render aspect of the page life cycle (i may cover this in another post).
The asynch method is called from the the view on clicking the submit button (read up on MVC if this appears odd) where the bus is called and a Requestmessage sent to the bus. Some of the semantics here are very much monorail so the main point is:
a Request Message was sent to the Bus to be processed in an asynch fashion.
If you have debugging on with a break point in the DashboardApplication.HandleRequestMessage method you will see the bus has routed the request here. The method simply creates a basic response and publishes that response. Because the the DemoController is a subscriber to the ResponseMessage type it receives that message via its consume method, assigns it to a local variable and calls the request to be completed, which inturn calls the EndAsynch method.

the key points are the

Consumes<responsemessage>.For<guid>

on the controller with its consume methods and the asynch calls to the bus. each framework will do this slightly differently

container.Resolve<IServiceBus>().Subscribe<RequestMessage>(HandleRequestMessage);

the subscribing to the request message

container.Resolve<IServiceBus>().Publish(response);

the publishing of the response message

If you want to see the inner working then the 3 projects under the mass transit folder contain all the juicy stuff. typically these would just be refence dll's but the whole idea of sample is to see how the code works :)
Hopefully next up I may do a classic Asp.Net example to see if i actually get the concepts correctly (reading and writing are not the same things!) and can use the asynch methods from there.


--------------------------------------
Setting up MSMQ

NB On XP You must have an edition that supports MSMQ (ie not home)

Go in to Control panel > add or remove programmes
Select the add/remove windows components
Select Message Queuing if it is not already selected and add it.

Now if you go to “Control Panel” > “Administrative Tools” > “Computer Management” under the “Services and Applications” branch, when expanded, you should see a “Message Queuing” branch.
If so you have MSMQ set up.

You now need to set up queues for an application to uses

From : http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.ebd.eai.help.src/setting_up_msmq.htm
Setting Up Microsoft Message Queuing (MSMQ)

To Set up MSMQ on your Server:

1. Go to Control Panel -> Add/Remove Programs -> Add/Remove Windows Components.

2. Select Message Queuing Services Component from the Windows Component Wizard.

3. Follow the directions provided by the Queuing Services Wizard.

4. After completing the Queuing Services Wizard, go to Control Panel -> Administrative Tools -> Computer Management -> Services and Applications -> Message Queuing.

To Create a Public Queue:

1. Right click the Public Queues Directory.

2. Select New.

3. Select Public Queue.

4. In the Queue Name Dialogue Box, enter the Queue Name, where the format is [machine_name]\[queue_name].

To Create a Private Queue:

1. Right click the Private Queues Directory.

2. Select New.

3. Select Private Queue.

4. In the Queue Name Dialogue Box, enter the Queue Name, where the format is [machine_name]\private$\[queue_name].

For Mass Transit you will need to create a private queue of the name “test_servicebus” and leave the default setting of NOT transactional.