Paul Gielens:ThoughtsService

another Endpoint to my thoughts

News

Syndication

Ads


Favorites

Projects

August 2005 - Posts

Service Anti-Patterns, Command vs. Document Message

Via Arjen, Service Pattern and Anti-Patterns. While reading this article last night I got sucked into thinking about using a Document Message pattern:

 

1.)

[WebMethod()]

public FindCustomersByCountryResponse FindCustomersByCountry(FindCustomersByCountryRequest request)

{

       ..

}

 

vs a Comand Message pattern.

 

2.)

[WebMethod()]

public Customer[] FindCustomersByCountry(string country)

{

       ..

}

 

or

 

3.)

[WebMethod()]

public Customer[] FindCustomersByCountry(Country country)

{

       ..

}

 

Although EIP gives very clear guidance on when to use what, my experience is that most services based on Web Services technology use the Command Message pattern where services based upon MQ technology make good use out of both Message pattern styles. Why is that? Given the fact that services are build to last, I think I prefer, in the context of a Web Service, Document Messages and explicitly design a request/reply messages as if it is a Command Message. …and stay away from option 2 altogether.

 

Any thoughts?

*Update, Dutch .NET Developers Alliance

Early 2004 I called out to gather Dutch .NET bloggers in a single OPML file. I am pretty sure this helped the community to overcome and exceed the boundaries of great organizations (like dotNED and SDN) and the companies for which we work. A good example is the collaboration of several Dutch bloggers spreading Tech Ed 2005 news.

The list is still growing: Pieter de Bruin, Mark Willems, Ronald Lemmen, Maarten Mullender, Olaf Conijn, Teun Duynstee, Michiel van Otegem, Hassan Fadili, Martien van Steenbergen, Vincent Maas, Martijn Hoogendoorn, Scott van Vliet and Erwyn van der Meer.

Grab the OPML file here which contains allot of Dutch .Net developers. Are you a Dutch .Net developer and want your name on our list, drop a line pgielens@gmail.com

edit: included Scott van Vliet
edit2: included Erwyn van der Meer

Posted: Aug 13 2005, 11:18 AM by p.gielens | with 4 comment(s)
Filed under:
Simplified Enterprise Library Design-time Configuration Support

A while back I wrote an article on Extending the Enterprise Library Configuration Tool to maintain your Application Configuration. In this article I gave practical guidance in integrating your own configuration in the Enterprise Library Configuration Tool. The FomsDesignManagar class contained a lot of code which could be easily refactored into a base class. The same counts for the ConfigurationNode class. A copy paste version of the DesignManagerBase class.

 

public abstract class DesignManagerBase : IConfigurationDesignManager

{

       public DesignManagerBase()

       {

       }

 

       #region IConfigurationDesignManager Implementation

 

       public void Register(IServiceProvider serviceProvider)

       {

             RegisterCommands(serviceProvider);

       }

 

 

       public void Save(IServiceProvider serviceProvider)

       {

             ConfigurationContext configurationContext = ServiceHelper.GetCurrentConfigurationContext(serviceProvider);

 

             if (configurationContext.IsValidSection(GetSectionName()))

             {

                    ConfigurationNodeBase node = null;

 

                    try

                    {

                           IUIHierarchy hierarchy = ServiceHelper.GetCurrentHierarchy(serviceProvider);

                           node = hierarchy.FindNodeByType(GetConfigurationNodeType()) as ConfigurationNodeBase;

                           if (node == null)

                           {

                                  return;

                           }

 

                           object settings = node.GetSettings();

                           configurationContext.WriteConfiguration(GetSectionName(), settings);

                    }

                    catch (ConfigurationException e)

                    {

                           ServiceHelper.LogError(serviceProvider, node, e);

                    }

                    catch (InvalidOperationException e)

                    {

                           ServiceHelper.LogError(serviceProvider, node, e);

                    }

             }

       }

 

 

       public void Open(IServiceProvider serviceProvider)

       {

             ConfigurationContext configurationContext = ServiceHelper.GetCurrentConfigurationContext(serviceProvider);

 

             if (configurationContext.IsValidSection(GetSectionName()))

             {

                    ConfigurationNode node = null;

 

                    try

                    {

                           object settings = configurationContext.GetConfiguration(GetSectionName());

                           node = CreateConfigurationNode(settings);

                           ConfigurationNode rootConfNode = ServiceHelper.GetCurrentRootNode(serviceProvider);

                           rootConfNode.Nodes.Add(node);

                    }

                    catch (ConfigurationException e)

                    {

                           ServiceHelper.LogError(serviceProvider, node, e);

                    }

             }

       }

 

 

       public void BuildContext(IServiceProvider serviceProvider, ConfigurationDictionary configurationDictionary)

       {

             IUIHierarchy hierarchy = ServiceHelper.GetCurrentHierarchy(serviceProvider);

             ConfigurationNodeBase node = hierarchy.FindNodeByType(GetConfigurationNodeType()) as ConfigurationNodeBase;

 

             if (node != null)

             {

                    object settings = node.GetSettings();

                    configurationDictionary[GetSectionName()] = settings;

             }

       }

 

       #endregion

 

       protected virtual void RegisterCommands(IServiceProvider serviceProvider)

       {

              IUIHierarchyService hierarchyService = serviceProvider.GetService(typeof (IUIHierarchyService)) as IUIHierarchyService;

             IUIHierarchy currentHierarchy = hierarchyService.SelectedHierarchy;

             bool containsNode = currentHierarchy.ContainsNodeType(GetConfigurationNodeType());

             IMenuContainerService menuService = serviceProvider.GetService(typeof (IMenuContainerService)) as IMenuContainerService;

 

             ConfigurationMenuItem item = new ConfigurationMenuItem(

                    GetMenuItemText(),

                    new AddConfigurationSectionCommand(serviceProvider, GetConfigurationNodeType(), GetSectionName()),

                    ServiceHelper.GetCurrentRootNode(serviceProvider),

                    Shortcut.None,

                    GetStatusBarText(),

                    InsertionPoint.New);

 

             item.Enabled = !containsNode;

             menuService.MenuItems.Add(item);

       }

 

 

       protected abstract string GetSectionName();

       protected abstract string GetMenuItemText();

       protected abstract string GetStatusBarText();

       protected abstract ConfigurationNodeBase CreateConfigurationNode(object settings);

       protected abstract Type GetConfigurationNodeType();

}

 

A descendant should then implement the following methods:

 

protected abstract string GetSectionName();

protected abstract string GetMenuItemText();

protected abstract string GetStatusBarText();

protected abstract ConfigurationNodeBase CreateConfigurationNode(object settings);

protected abstract Type GetConfigurationNodeType();

 

And the ConfigurationNodeBase class.

 

public abstract class ConfigurationNodeBase : ConfigurationNode

{

       public abstract object GetSettings();

 

       [ReadOnly(true)]

       public override string Name

       {

             get { return base.Name; }

             set { base.Name = value; }

       }

 

 

       protected override void OnSited()

       {

             base.OnSited();

             Site.Name = GetComponentName();

       }

 

 

       protected abstract string GetComponentName();

}

 

Remember the bulky FormsDesignManager in the first article? This is what it looks like when inheriting the DesignManagerBase class.

 

public class FormsDesignManager : DesignManagerBase

{

       private static string MENUITEM_TEXT = "Formulieren Configuration";

       private static string STATUSBAR_TEXT = "Formulieren Configuration";

 

 

       public FormsDesignManager() : base()

       {

       }

 

       #region DesignManagerBase Implementation

 

       protected override string GetSectionName()

       {

             return FormsSettings.SectionName;

       }

 

 

       protected override ConfigurationNodeBase CreateConfigurationNode(object settings)

       {

             return new FormsSettingsNode((FormsSettings) settings);

       }

 

 

       protected override Type GetConfigurationNodeType()

       {

             return typeof (FormsSettingsNode);

       }

 

 

       protected <