(Art courtesy of my girls who were very excited for me!  My wife wasn't sure what logo to use so she went with the familiar Windows one, lol!) 

I am excited and honored to receive a Microsoft MVP award in the Solution Architect category. 

Thanks to Clint Edmonson who I'm sure had much to do with my nomination and a congratulations to Lee Brandt from KC who is also a recipient of the MVP award.  I'm definitely looking forward to meeting the other 2009 MVPs as well as the MVP alumni who are made up of many of the software thought leaders I keep tabs on via blogs and twitter.

This was definitely a welcome surprise after a couple weeks where I've been struggling to stay motivated at REJIS.  I put a lot into my work at work and home and the balance has been a little too far out of whack and it's time to bring it back.  I'm looking forward to a few days off and some time with the family, hitting the trails, and of course my Xbox :)

---

Recent Happenings

If you want to read a little more about what I'm up to check out this interview I submitted to "I'm a VB".

Upcoming Events

St Louis Day of .NET, August 28 & 29 – Sign up now

  • I will be delivering some short Q&A sessions on WCF, so stay tuned to the schedule for more information.

NIEM National Training Event, September 30-October 2nd – Sign up here

  • I will be delivering three sessions over the two days.  Two will cover using NIEM in your SOA, and one will cover working with NIEM in the .NET framework.  I'm very excited about this conference and the opportunity to speak with some of the real movers & shakers in public safety information sharing efforts.  The days will be packed with great sessions and the evenings full of NIEM community meetings.

I hope everyone has a safe and happy 4th of July!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 7/1/2009 at 5:36 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Registration is open!  Sign up today!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 6/30/2009 at 5:06 PM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

Lately problems have been on my mind.  At home we've had some fun with torrential rain and the kids; at work we've been having some growing pains as we move to more services and service agents (or clients).  Having problems is not a bad thing.  Having new problems can be a sign that you are doing something right. 

A few years back I read an article in Men's Health that I like to quote from time to time.  "Doing old things in new ways, new things in new ways, or new things in old ways.  The only thing they hate are the old ways of doing old things."  The context for the article was what a manager was looking for in people who can make changes in an organization.  In this context it's safe to apply by realizing that as long as you continue doing old things in old ways you will have the same problems and they will never change.

It is only when you transition to the new ways that you will encounter new problems.  It does not mean the new ways are bad so long as you don't have new problems and the same old problems.  If you have both then you're doing something wrong.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 6/7/2009 at 10:18 AM
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

As we've moved to using more shared assemblies in the REJIS Law Enforcement group we've run into some problems where someone gets an old copy of an assembly or we are trying to figure out what a shared assembly is referencing without having to open up the full solution and source code (or rolling back to an old version of source).  This is going to happen, so don't let it scare you away from sharing code.  Shared code is good code, but with that comes certain things that will undoubtedly happen; having tools and procedures in place to handle these things make life much easier. Trust me.

ILDASM.exe is one handy tool provided by Microsoft for letting you peer inside the assembly, and most importantly, you can see the manifest file which is where the dependencies can be found.

To open ILDASM, head to a Visual Studio Command Prompt and type in 'ILDASM' (no quotes).  Once in, just open your assembly and double-click the manifest to view the dependencies.

ILDASM-01

You can also do the same thing in Reflector, which is another great (free) tool for troubleshooting .NET assemblies and peering into bits you may not have control over.

Just open up Reflector and load the assembly you want to look at and check out the Visual Studio style "references" tree menu to see what dependencies there are.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 6/1/2009 at 6:49 PM
Tags: , ,
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

The slide deck from my "Diving Into Services with WCF" presentation at Monday's St. Louis .NET User Group meeting is posted to Slideshare.  Thanks to everyone who was there and for sticking through to the end.  There was a lot of material to cover and I was pretty tired after talking for an hour and a half. 

I will post the code examples early next week after I clean up a few items.  See you next time!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 5/19/2009 at 6:54 PM
Tags: ,
Categories: Public Appearances
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

I'm presenting at tomorrow's St Louis .NET User Group meeting and will focus on WCF

"Windows Communication Foundation (WCF) is the framework for building distributed applications in .NET. WCF provides a foundation to build and expose services across a variety of communication methods. In this session we will cover the ABC's of WCF and then dive into a real-world example WCF service that demonstrates how WCF can support services the way you need it to."

Hope to see you there!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 5/17/2009 at 6:16 PM
Tags: , ,
Categories: Public Appearances
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

REJIS enabled instant messaging within our organization.  This has been one of the more exciting developments as of late because I personally find IM to be a great way to have short conversations without needing to break away from what you are doing or take your headphones off to use the phone.  E-mail is not a medium for conversations.  Too often will people include multiple items in an E-mail and only a few actually get responses.  With IM it's hard to ignore someone asking you Can you do A, B, and C?  IM is like the person is actually standing there asking you, except that it is on your screen and they can see if you start typing.  You have to be pretty good at ignoring people in person to ignore IM.  If you turn off and the person is smart enough, they will come to your desk anyway. 

IM is not for everyone.  Some people can't handle another channel for communication.  Personally, I could do most of my day-to-day tasks with IM, a few phone calls and in person meetings only when really necessary.  Many of the projects I work on already have few, if any, in person meetings for the technical staff at the various partners.  These are by no means small projects either.  To coordinate testing we'll often use IM rather than E-mail or keeping conference lines open.  For me this means I have to use Google Talk on my Blackberry (because we do not allow other IM connections internally).  Most of the conversations go something like: "Hey we sent you a document but our process timed out, what happened?" 

"Let me look at it and I'll let you know." (time lapse) "Looks like an error during an internal process, we'll fix it and let you know."

"Ok, we'll send another when you're ready"

Any further details are handled in a phone call or E-mail.  In terms of simple coordination you can't beat IM as a medium for brokering this communication.  IM is not for everyone or everything, but it's darn handy to have.

Twitter has been another interesting medium for conversations and meeting people.  Most recently, my post about CodeRush netted DevExpress as a follower on Twitter and connected me to some of their evangelists and other CodeRush enthusiasts.  Similarly LinkedIn is proving valuable as I am making connections with some people in the justice industry that will be able to help us solve some problems on our technology transformation effort. 

Although I haven't been on much lately, I also game on Xbox Live with one of the managers at REJIS as well as peers from other partner organizations.  I would be remiss to say that we never had a few post-mortem meetings while shooting zombies or blowing up terrorist camps.

While on the topic of conversations, not long ago I recorded an audio interview with Clint Edmonson on the challenges of applying SOA concepts.  The interview is up on the Thirsty Developer site.  Give it a listen and let me know what you think!

Lastly, REJIS needs developers.  We have openings for .NET developers and as one of the lead developers I can tell you we need good people.  REJIS is currently using .NET 3.5 SP1 including LINQ to XML, WCF, WPF and we're using Microsoft's Enterprise Library and Unity.  The projects we work on are mission critical apps that service a variety of purposes for criminal justice agencies.  There is no shortage of work and believe me when I say you'll get very valuable experience with things you won't work with at other places (yes, there are things we do that are not discussed here).  Take a look and apply on-line.  Please don't send me your resume unless you are looking for some peer review…I don't make the decisions :)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 4/28/2009 at 5:22 PM
Tags: , ,
Categories: Random Thoughts
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

At the 2008 Day of Dot Net I won a software prize and took up Scott Spradlin on a DevExpress subscription to CodeRush and Refactor! Pro.  Scott purchased my electronic license and forwarded the information and I started working with both products at work and at home.  I was happy to see that both CodeRush and Refactor! supported Visual Basic and C# out of the box.  The other refactoring tool I am familiar with, Reshaper, is C# specific.  While I have come to really enjoy C#, Visual Basic is still a key language I use and it also has a few features that C# lacks (yes I'm talking about XML Literals and they are immensely useful for those of us dealing with lots of XML).

I originally installed the 2008 version but at the end of the first quarter I saw that the 2009 version was out.  I recently snagged that and started putting it to work in some of my work and home projects.  I noticed major performance improvements on both my work and personal machines, as well as some helper features that let you choose whether to use the DXCore functionality or the Visual Studio functionality for specific actions or key commands.

One of the main features that has been really useful for me as I work to learn the C# syntax is the CodeRush assistance window.  The assistance window gives you context sensitive key commands based on where your cursor is.  The commands are the same across both VB and C# so if I forget the syntax for creating an overloaded constructor I can simply hit 'cc [space]' (no quotes) and activate the CodeRush constructor template which allows you to choose with properties or private fields to use as arguments in the constructor.

A few favorite features and short-cuts:

  • The "What happened?" dialog which lets you choose to override default studio behaviors with CodeRush behaviors.
  • Constructor Overload short-cut keys: cc space
  • Namespace optimizer: Hover over the right margin for code "issues".
  • Move type to file (Multiple classes in one file, hover over name of class to move, click on the three dots and choose "Move type to file")
  • Quick property short-cut keys: p space or ps space for a string property, etc
  • Extract interface: Hover over class hit ctrl + ` (default refactoring key)
  • C# automatic properties short-cut keys: as space for a string ao space for object, etc.

DevExpress has a free trial that you can check out if you are interested.  The pricing on CodeRush is $99 and I believe the pricing on the CodeRush and Refactor! Pro is $249.  I'll find out next year when I renew.  I don't spring for any development tools on my own dime but this one is useful enough that I'll be happy to renew it next winter.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 4/26/2009 at 9:04 AM
Tags: , , ,
Categories: Software Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed
 
 

During a refactoring of a WCF solution I was converting all the various services in the solution to use dependency injection with constructors.  One of the services was configured as a singleton using the ServiceBehavior InstanceContextMode.Single.  This particular service controls a resource that is best left for a singleton because it has an open socket listener that receives responses from our mainframe systems.  The service was also configured for transactions and has the ReleaseServiceInstanceOnTransactionComplete explicitly set to false.

When the other developer on the project fired up the test harness for the services he was receiving the message "The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host. ".  After testing a few theories I noticed that the service was marked up with the InstanceContextMode behavior.  I removed the attribute and tested the service and it worked just fine which lead me to draw a conclusion about how WCF handles the InstanceContextMode attribute.

Because you are telling WCF to manage that service instances lifetime it makes sense that it would require a default constructor because WCF is going to be instantiating and disposing of the service instance.  When I refactored the service to with no default constructor that was a breaking change for the WCF infrastructure.  So the question remains, can Unity handle a singleton service instance?

To test Unity with a Singleton service I followed the steps in my previous article on Unity and WCF and created an IInstanceProvider, IServiceBehavior, and a custom ServiceHost.  The results were what I expected.  Each call to the service was handled by the singleton instance of the service whose lifetime was being managed by the Unity container.

using System;

namespace Service
{
    //[System.ServiceModel.ServiceBehavior(InstanceContextMode=System.ServiceModel.InstanceContextMode.Single)]
    public class PersonService : Contracts.IPersonService
    {
        private Guid _instanceId;

        /// <summary>
        /// Initializes a new instance of the PersonService class.
        /// </summary>
        public PersonService()
        {
            _instanceId = Guid.NewGuid();
        }

        #region IPersonService Members

        public Contracts.PersonResponse SavePersonRecord(Contracts.PersonRequest request)
        {
            return new Contracts.PersonResponse(_instanceId.ToString(), 
String.Format("Added Person - {0}", request.Person.Name)); } public Contracts.PersonResponse DeletePersonRecord(Contracts.PersonRequest request) { return new Contracts.PersonResponse(_instanceId.ToString(),
String.Format("Deleted Person - {0}", request.Person.Name)); }
#endregion } }

Unity_Singleton_Output

The client calls the SavePersonRecord method then subsequently the delete person method.  As you can see the Instance Id returned by the service is the same for both calls.  Removing the lifetime element from the Unity configuration results in two different instance Id's returning from the service because the default behavior for WCF is to create a new instance per call to the service.

I ran one final test and that was to remove the default constructor and require the Instance Id to be passed to the constructor:

using System;

namespace Service
{
    //[System.ServiceModel.ServiceBehavior(InstanceContextMode=System.ServiceModel.InstanceContextMode.Single)]
    public class PersonService : Contracts.IPersonService
    {
        private Guid _instanceId;

        /// <summary>
        /// Initializes a new instance of the PersonService class.
        /// </summary>
        /// <param name="instanceId"></param>
        public PersonService(string instanceId)
        {
            _instanceId = new Guid(instanceId);
        }

        #region IPersonService Members

        public Contracts.PersonResponse SavePersonRecord(Contracts.PersonRequest request)
        {
            return new Contracts.PersonResponse(_instanceId.ToString(), 
String.Format("Added Person - {0}", request.Person.Name)); } public Contracts.PersonResponse DeletePersonRecord(Contracts.PersonRequest request) { return new Contracts.PersonResponse(_instanceId.ToString(),
String.Format("Deleted Person - {0}", request.Person.Name)); } #endregion } }

The Unity configuration now looks like so:

<unity>
  <typeAliases>
    <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, 
Microsoft.Practices.Unity
"
/> <typeAlias alias="IPersonService" type="Contracts.IPersonService, Contracts" /> </typeAliases> <containers> <container> <types> <type type="IPersonService" mapTo="Service.PersonService, Service"> <lifetime type="singleton" /> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration
"
> <constructor> <param name="instanceId" parameterType="System.String, mscorlib"> <value value="2423f423-a4da-4306-9ba1-452214c517d6"/> </param> </constructor> </typeConfig> </type> </types> </container> </containers> </unity>

Hopefully it is no surprise that the results of calling the service are the same as the screenshot posted above.

I still need to test this with transactions but I believe using the right set of options will prevent WCF from disposing your singleton and allow your custom Unity service host to handle that.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 4/25/2009 at 2:17 PM
Tags: , , ,
Categories: WCF
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed
 
 

Last week while researching an issue with one of our systems I discovered that six days worth of messages were missing from a queue.  After the initial panic we started researching.  One of my colleagues discovered the Transactional Dead-Letter queue had a large amount of messages piled up in it.  I had read some about that queue but never really dug into it.  This gem of an article got me started on a path that would ultimately lead to a best of breed type solution.

The solution from Billy Dunlop's article has you change the ServiceBehavior AddressFilterMode to "Any".  What this does is allows your queued service to receive messages destined for any endpoint, so long as the message body is what it expects.  I have used this in the past for poison queues and it made perfect sense here.  However, we had one other problem.  Some of the messages in the dead-letter queue were for other queued services and simply changing one of our services to use the dead letter queue as it's endpoint would not work right.  The solution is to use a more generic contract similar to the WCF Message Router covered in this MSDN article.

I took the router approach and created a router service and console application to host it.  For work I did all this in VB.NET.  As a tribute to my very good friend David Risko I spent the weekend rewriting the whole thing in C#.  This was my first shot at writing something from scratch in C#, so if you see something that could be condensed or written in a more clear manner please do let me know.

The default Time-to-live on the NetMsmqBinding is 1 day.  This can be adjusted in configuration or through code when you create the binding.  As a simple test you can create a NetMsmq service client and set your binding time-to-live to something ridiculous like 30 seconds (it's a time span so you can do this with TimeSpan.FromSeconds(int)).  Watch the message hit your transactional queue and refresh and after 30 seconds, *poof*, message gone and you can now find it in your Transactional Dead-Letter queue.

Feel free to follow the code below or download the .ZIP file with the solution.  The solution was created in Visual Studio 2008 SP1.

On to the code!

The contracts – included are the Service Contract  which will be used by the router service and the Channel contract which will be used by the MessageRouter class to resend the message to it's intended destination.  The service contract uses System.ServiceModel.Channels.Message as it's input message.  This allows the router to receive any WCF message for any service without having to understand the body.  This is a hugely powerful ability that should be used with great care.

namespace CD.ServiceModel.NetMsmqRouter.Contracts
{
   
/// <summary>
    ///
Service contract interface for the message router service.
  
/// </summary>
   
[System.ServiceModel.ServiceContract]
    public interface
IMessageRouterService
   
{
        [System.ServiceModel.OperationContract(IsOneWay=true,Action="*")]
        void Route(System.ServiceModel.Channels.Message message);
    }

    public interface IMessageRouterChannel : System.ServiceModel.IClientChannel,
IMessageRouterService
   
{

    }
}

The biggest piece I had to get my head around when learning WCF was the notion of the contract.  The same interface will be implemented by both the service and client but each one implements it differently.  The service implements it from the perspective of receiving the message and the client implements it from the perspective of sending the message.

Next up is the service implementation.  Pretty straight forward and it does two things – uses the MessageWriter class to save the message to disk (in case something really bad happens) and then uses the MessageRouter class to send the message to it's original intended destination.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CD.ServiceModel.NetMsmqRouter.Service
{
    [System.ServiceModel.ServiceBehavior(AddressFilterMode = System.ServiceModel.AddressFilterMode.Any,
ValidateMustUnderstand = false)] public class RouterService : Contracts.
IMessageRouterService { private MessageWriter _writer; private MessageRouter _router; /// <summary> /// Initializes a new instance of the RouterService class. /// </summary> public RouterService() { _writer = new MessageWriter(Properties.Settings.Default.MessageWriterPath); _router = new MessageRouter(Properties.Settings.Default.NetMsmqBindingConfigurationName); } #region IMessageRouterService Members [System.ServiceModel.OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)] public void Route(System.ServiceModel.Channels.Message message) { try { System.Diagnostics.Trace.WriteLine("----- Message Received -----"); System.ServiceModel.Channels.MessageBuffer messageCopyToWrite = message.CreateBufferedCopy(Int32.MaxValue); _writer.Write(messageCopyToWrite); _router.RouteMessage(messageCopyToWrite.CreateMessage()); System.Diagnostics.Trace.WriteLine("----- Message Processing Complete -----"); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); throw; } } #endregion } }

The service is geared to work with the Transactional Dead-Letter queue which is why the Route method is marked up with the TransactionAutoComplete and TransactionScopeRequired attributes.  Within the try/catch block the service does not handle the exception in order to facilitate the aborting of the transaction scope the message is received under and this is the recommended pattern when you use TransactionAutoComplete = true.  If we did not throw here the scope would complete and the message would be lost if it was not routed to it's original queue.

The message writer class has one responsibility – write the message to the path supplied in it's constructor.  The message router class is the one we'll focus on next as it is responsible for taking the original message and routing it to the messages original destination:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;

namespace CD.ServiceModel.NetMsmqRouter.Service
{
    /// <summary>
    /// Routes a message to its original destination
    /// </summary>
    internal class MessageRouter
    {
        private string _bindingConfigurationName;

        /// <summary>
        /// Creates a new instance of the message router class.
        /// </summary>
        /// <param name="bindingConfigurationName"></param>
        public MessageRouter(string bindingConfigurationName)
        {
            _bindingConfigurationName = bindingConfigurationName;
        }

        /// <summary>
        /// Gets an instance of the NetMsmqBinding
        /// </summary>
        /// <returns></returns>
        /// <remarks>Returns the default binding if no configuration name was specified.</remarks>
        private NetMsmqBinding GetBinding()
        {
            if (!string.IsNullOrEmpty(_bindingConfigurationName))
            {
                return new NetMsmqBinding(_bindingConfigurationName);
            }
            else
            {
                return new NetMsmqBinding();
            }
        }

        /// <summary>
        /// Returns an instance of a Contracts.IMessageRouterChannel
        /// </summary>
        /// <param name="binding"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        private Contracts.IMessageRouterChannel GetChannel(NetMsmqBinding binding, string address)
        {
            return new ChannelFactory<Contracts.IMessageRouterChannel>(binding, address).CreateChannel();
        }

        /// <summary>
        /// Routes the message to its destination uri.
        /// </summary>
        /// <param name="message">The message to send</param>
        public void RouteMessage(System.ServiceModel.Channels.Message message)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("Message destination: {0}", message.Headers.To.ToString()));
            Uri destinationUri = message.Headers.To;
            System.ServiceModel.NetMsmqBinding binding = GetBinding();
            using (Contracts.IMessageRouterChannel channel = GetChannel(binding, destinationUri.ToString()))
            {
                using (System.Transactions.TransactionScope scope = 
new System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew)) {
try { channel.Route(message); scope.Complete(); } catch (Exception ex) { Trace.WriteLine(String.Format("**** Error ****\n{0}", ex.ToString())); channel.Abort(); throw; } } } } } }

All that is left is to wire up the service in the console host and then add the proper configuration elements.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using CD.ServiceModel.NetMsmqRouter;

namespace RouterServiceConsoleHost
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.AutoFlush = true;
            System.Diagnostics.Trace.WriteLine("Starting service.");
            StartServiceHost(typeof(CD.ServiceModel.NetMsmqRouter.Service.RouterService));
        }

        public static void StartServiceHost(Type serviceType)
        {
            using (System.ServiceModel.ServiceHost serviceHost = new System.ServiceModel.ServiceHost(serviceType))
            {
                serviceHost.Open();
                    
                Trace.WriteLine("Service started...press <Enter> to exit");
                Trace.WriteLine("");
                Trace.WriteLine("");

                Console.ReadLine();
                if (serviceHost.State == System.ServiceModel.CommunicationState.Faulted)
                {
                    serviceHost.Abort();
                }
                serviceHost.Close();
            }
            
        }
    }
}

And the configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, 
System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
"
> <section name="CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
" requirePermission="false"
/> </sectionGroup> </configSections> <applicationSettings> <CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings> <setting name="MessageWriterPath" serializeAs="String"> <value>C:\Users\Chris\Desktop\RecoveryRouter\</value> </setting> <setting name="NetMsmqBindingConfigurationName" serializeAs="String"> <value>RecoveryRouterNetMsmqBinding</value> </setting> </CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings> </applicationSettings> <system.serviceModel> <bindings> <netMsmqBinding> <binding name="RecoveryRouterNetMsmqBinding" maxReceivedMessageSize="4194304"
maxRetryCycles="2" receiveRetryCount="1" timeToLive="1"
> <readerQuotas maxStringContentLength="4194304"/> <security mode="None"> <transport msmqProtectionLevel="None"/> </security> </binding> </netMsmqBinding> </bindings> <services> <service name="CD.ServiceModel.NetMsmqRouter.Service.RouterService"> <endpoint address="net.msmq://localhost/system$;DeadXact" binding="netMsmqBinding"
bindingConfiguration="RecoveryRouterNetMsmqBinding" name="RecoveryRouterService"
contract="CD.ServiceModel.NetMsmqRouter.Contracts.IMessageRouterService"
/> </service> </services> </system.serviceModel> </configuration>
Technorati Tags: ,

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Chris
Posted on: 4/1/2009 at 5:47 PM
Tags: ,
Categories: WCF
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed