Saturday, May 30, 2009
Debuggable Self-Host Windows Service Projects
When developing self-hosted WCF services, you really need two things: - A windows service project that will be the host for the deployed environment.
- A console self-host project for easy debugging while developing the service.
Yes, there is also the option to use a WCF Service Library project with its associated WcfServiceHost.exe process that self hosts the service for debugging. However, I have run into too many occasions where something is going wrong and not having direct access to the hosting code wastes more cycles than it takes to set up my own service host, so other than quick demos, I never use the WcfServiceHost.exe in production development. Having two separate projects to address 1 & 2 above is not really that great either, but if you try to run a service project in the debugger, you get an error telling you it can only be run through the services panel in Windows. However, through a quick and easy pattern, you can make your service projects so they run as a console for development, but run as a service just fine when installed. Step 1: Create a Windows Service project for the self host environment. This is just the standard selection in the project dialog for a Windows Service project. Once you have your service class, rename it as appropriate and right click on the designer surface to add an installer class for the service. Standard stuff here. Step 2: Implement your hosting code in a separate class from the service class itself. For example, here is a very simple hosting class that can be used for any service in any project (with some appropriate exception handling and logging added in for production purposes): public class SelfHost<T>
{
ServiceHost m_Host;
public void Start()
{
m_Host = new ServiceHost(typeof(T));
m_Host.Open();
}
public void Stop()
{
m_Host.Close();
}
}
From the service class itself, you can just instantiate an this class and call its Start and Stop methods.
public partial class SimpleServiceHostService : ServiceBase
{
SelfHost<SomeService> m_Host = new SelfHost<SomeService>();
public SimpleServiceHostService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
m_Host.Start();
}
protected override void OnStop()
{
m_Host.Stop();
}
}
Now when you install this service, the service host will be started and stopped through the services panel or automatically depending on the service configuration.
Step 3: Modify the Main method to start conditionally as a Console or a service.
Modify the default main declaration with no parameter to the signature for a main that takes a string[] of arguments. If arguments are present, run the code as if you are in a console app. If no arguments, call the default code for starting it as a service. For the console host mode, just call the Start and Stop methods on an instance of your host class just like the windows service did.
static void Main(string[] args)
{
// Run as console if there are command line arguments
if (args.Length > 0)
{
SelfHost<SomeService> host = new SelfHost<SomeService>();
host.Start();
Console.WriteLine("Press Enter to Exit...");
Console.ReadLine();
host.Stop();
}
else // run as service
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new SimpleServiceHostService()
};
ServiceBase.Run(ServicesToRun);
}
}
Step 4: Modify the project properties to be a console application and add a debug command line parameter.
That is basically it. Change the code shown above to use your service type, add an app.config with the appropriate WCF service code, and you are ready to run as a console app in the debugger, but when you build and install your service as a service, it will run fine as that as well.
You can download a full sample application here.
Wednesday, May 13, 2009
TechEd SOA401 – Developing Service Oriented Workflows
This morning I am giving the subject session at TechEd. For those of you that attended, thanks! You can probably jump to the link at the bottom for the demos unless you want a quick review of what we covered by reading the rest of this post. This session discusses .NET 3.5 Workflow Services, and I also touch on what is different in .NET 4.0 throughout and at the end. I also have a brief discussion at the end about cloud workflows, using workflow activities from .NET Services and running workflows in the cloud with Windows Azure. In the talk, I demonstrate the use of the ReceiveActivity for exposing service operations from a workflow. I show how to add the receive activity to a workflow, hook it up to a service contract and the operations on that contract, how to bind the incoming parameters to other workflow properties and how to retrieve the return result from workflow properties through a binding. I then show how to host the workflow as a service using the WorkflowServiceHost class, how to get a reference to the WorkflowRuntime from the host (to hook up to workflow events), and how to configure the right bindings (context bindings) to expose the workflow. Then I write a quick client that is able to call the workflow to get it running and pass parameters to it. Then I jump to a more complicated workflow that represents a loan application process as a state machine workflow. The loan application is submitted through a service call, and then approve or reject actions can be taken through service calls. I show how calls from the same client work out automatically through the passing of the instance ID through the context bindings, and how to allow multiple clients to interact with the same workflow by setting and getting the instance ID out of the context. Then I show that the loan application workflow also needs to make service calls out to another credit checking service. So I demonstrate how you can use a SendActivity to act as a dynamic proxy in the workflow to call another service. Like the ReceiveActivity, you use bindings on dynamic properties to provide values for the outgoing parameters and to deal with any returned values. I also discuss the limitations of the SendActivity and how to work around it by creating a simple custom activity to encapsulate a normal WCF proxy over which you have complete control. Then I show an application that is composed of two workflows, a parent workflow and a child workflow. The parent invokes the child workflow and gets results back from the child. The trick with this scenario is how you need to pass the context to the child workflow of the receive activity that the call will come back into in the parent workflow so that the workflow runtime can reassociate the incoming call with the right instance and right receive activity. If you want to take a look at the demos that do all of the above, here you go.
Thursday, May 07, 2009
NoVa Code Camp – 23 May
Update: Apparently I found a wormhole this morning and stated January instead of May. That would be May 23!
We have a code camp coming up on Saturday 23 May in Northern Virginia at the Reston Microsoft Training Center at 12012 Sunset Hills Rd, Reston, VA. There is a great line up with 4 tracks and over 20 speakers. I’ll be giving a session on Developing Service Oriented Workflows, come out and expand your brain!
|






| January, 2012 (1) |
| November, 2011 (4) |
| October, 2011 (1) |
| September, 2011 (2) |
| August, 2011 (1) |
| July, 2011 (1) |
| May, 2011 (5) |
| March, 2011 (4) |
| February, 2011 (2) |
| January, 2011 (3) |
| November, 2010 (4) |
| October, 2010 (1) |
| September, 2010 (5) |
| August, 2010 (5) |
| July, 2010 (6) |
| June, 2010 (8) |
| May, 2010 (2) |
| April, 2010 (2) |
| January, 2010 (1) |
| December, 2009 (3) |
| November, 2009 (2) |
| October, 2009 (3) |
| September, 2009 (3) |
| August, 2009 (2) |
| July, 2009 (3) |
| May, 2009 (3) |
| April, 2009 (2) |
| March, 2009 (1) |
| February, 2009 (2) |
| January, 2009 (2) |
| December, 2008 (1) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (4) |
| August, 2008 (2) |
| July, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (2) |
| April, 2008 (3) |
| February, 2008 (6) |
| January, 2008 (3) |
| December, 2007 (1) |
| November, 2007 (1) |
| October, 2007 (5) |
| September, 2007 (1) |
| July, 2007 (3) |
| June, 2007 (8) |
| April, 2007 (2) |
| March, 2007 (4) |
| February, 2007 (1) |
| December, 2006 (2) |
| November, 2006 (9) |
| October, 2006 (5) |
| September, 2006 (3) |
| August, 2006 (2) |
| July, 2006 (4) |
| June, 2006 (5) |
| May, 2006 (10) |
| April, 2006 (4) |
| March, 2006 (2) |
| February, 2006 (12) |
| January, 2006 (7) |
| December, 2005 (2) |
| November, 2005 (15) |
| October, 2005 (6) |
| September, 2005 (7) |
| August, 2005 (3) |
| July, 2005 (10) |
| June, 2005 (11) |
| May, 2005 (7) |
| April, 2005 (8) |
| March, 2005 (6) |
| February, 2005 (2) |
| January, 2005 (6) |
| December, 2004 (3) |
| November, 2004 (5) |
| October, 2004 (2) |
| September, 2004 (5) |
| August, 2004 (13) |
| July, 2004 (6) |
| June, 2004 (14) |
| May, 2004 (17) |
| April, 2004 (12) |
| March, 2004 (8) |
| February, 2004 (10) |
| January, 2004 (14) |
| December, 2003 (9) |
| November, 2003 (13) |
| October, 2003 (3) |


Sign In
|