EntLIb editor corrupts config files

I’ve tried to use Microsoft Enterprise Library(EntLIb) editor, as it was suggested in http://weblogs.asp.net/sukumarraju/archive/2011/11/07/configuring-wcf-service-to-utilise-enterprise-library-logging-application-to-log-data-to-database.aspx, but after changes all comments in config files were removed.
 
Always consider to move any Enterprise Library configurations to a separate file before editing.

Static methods not always bad for testability

Some time ago I’ve posted a few links about What is testable code?
Reading the links someone can feel that any static methods are bad for testability. However it is a wrong impression- static methods without external dependencies are good for testing.

 http://programmers.stackexchange.com/questions/5757/is-static-universally-evil-for-unit-testing-and-if-so-why-does-resharper-recom

There is nothing wrong with static methods and they are easy to test (so long as they don’t change any static data). For instance, think of a Maths library, which is good candidate for a static class with static methods 

 
Static methods which hold no state and cause no side effects should be easily unit testable. In fact, I consider such methods a “poor-man’s” form of functional programming; you hand the method an object or value, and it returns an object or value. Nothing more. I don’t see how such methods would negatively affect unit testing at all.
Alternatively you can mock anything – implemented by MS Fakes, TypeMock, JustMock and Moles.  They rely on .NET’sProfiling API. It can intercept any of your CIL instructions.
 
See related links  
 

Using PostSharp.Toolkit.Diagnostics, when not all developers have Pro licenses.

We have only couple of developers who are using PostSharp.Toolkit.Diagnostics and having  PostSharp Pro license .
However ther are much more developers , who are building our solution, but do not required Toolkit.Diagnostics XmlMulticast features, that are referred in %ProjName%.psproj file.
 
As a workaround I’ve suggested to to replace locally psproj file with dummy, that doesn’t have XmlMulticast(PostSharp feature that available only in Pro edition).
 
If a developer doesn’t have PostSharp Pro license, they shoul set  Environment variable POSTSHARP_PRO=false to effectively exclude psproj from the build on their local machine.
detailed instructions How to Add, Remove or Edit Environment variables in Windows 7 can be found at http://www.itechtalk.com/thread3595.html.
For Each project using PostSharp.Toolkit.Diagnostics  A subfolder PreBuild.Config has been created.
It includes minimal dev.psproj ,
PreBuild.cmd
and the full %ProjName%.psproj (e.g. MyProject.psproj ) that is used as a master version on build machine.
 

%ProjName%.psproj located in the root on local machines should kept  as minimal – the same as Dev.Configdev.psproj.

 

<?xml version=1.0 encoding=utf-8?>

<!–Empty project for developers without PostSharp Pro.

       Do NOT check-in   %ProjName%.psproj

       –>

       <Project xmlns=http://schemas.postsharp.org/1.0/configuration ReferenceDirectory={$ReferenceDirectory}>

              <Property Name=LoggingBackEnd Value=nlog />

              <Using File=default />

              <Tasks>

              </Tasks>

 

</Project>
 
For each project that uses toolkit insert into PreBuild Event command line
cmd /c $(ProjectDir)PreBuild.Config\PreBuild.cmd $(ProjectName)
 
File PreBuild.Config\PreBuild.cmd
rem developers without PostSharp Pro installed please set environment variable POSTSHARP_PRO=false
@rem see http://www.itechtalk.com/thread3595.html detailed instructions How to Add, Remove or Edit Environment variables in Windows 7
@REM Insert into PreBuild Event command line
@REM cmd /c $(ProjectDir)\PreBuild.Config\PreBuild.cmd $(ProjectName)
set ProjName=%1
set PSProjFile=..\%ProjName%.psproj
if ‘%POSTSHARP_PRO%==’false goto devPsproj
:proPsproj
set FileFrom=%ProjName%.psproj
@goto copyFile
:devPsproj
set FileFrom=dev.psproj
:copyFile
rem The current dir seems to be \bin\Debug for Library project or Windows Console/Services, but \bin for WAP(Webjet application project)
cd ..\..\PreBuild.Config

ATTRIB -R %PSProjFile%
copy /Y %FileFrom% %PSProjFile%
:end
@rem pause

VAB ValidationResults Extensions

We’ve started to actively used Microsoft Enterprise Library Validation Enterprise Block ( VAB)  and I was surprised , that a few commonly used  operations are not supplied(or I haven’t found them) out of the box.
See two extensions, that make use of VAB simpler

public static class ValidationResultsExtensions
       {
               public static string CombinedMessage( this ValidationResults results)
              {
                      string errorMessage = ( from res in results select String.Format( {0}:{1} , res.Key, res.Message)).ToDelimitedString( “;”);
                      return errorMessage;
              }
//Throws ValidationException if not valid
           public static void ValidateConstraints<T>( this T target)
           {
               Validator validator = ValidationFactory.CreateValidator<T>();
               var results = new ValidationResults();
               validator.Validate(target, results);
               if (results.IsValid == false)
               {
                   var errorMessage = results.CombinedMessage();
                   throw new ValidationException(errorMessage);
               }
           }
       }v

Using CollectionNotEmptyValidator

We recently started to use Microsoft Enterprise Library Validation Enterprise Block
 (VAB) to check interfaces between modules. One of the properties to validate is array  
of values, that should be not empty, and shoul include one of expected values. 
I found CollectionNotEmptyValidator at http://www.eggheadcafe.com/tutorials/xaml/9af7ac1a-d7f3-4e00-9aec-33ef1ec7d1a3/wpf-custom-validation-using-the-enterprise-library.aspx, that allows to  validate the property to satisfy part of requirements.
 
The class mostly works as is, I’ve only changed exception to Validation error if object to validate is not a collection.

        public override void DoValidate( object objectToValidate, object currentTarget, string key, ValidationResults validationResults)
              {

                      if (objectToValidate is ICollection)
                     {

                            if (((( ICollection)objectToValidate).Count != 0) == Negated)
                           {

                                  LogValidationResult(validationResults, MessageTemplate, currentTarget, key);

                           }

                     }

                     else
                     {

//throw new ApplicationException(“Object type not supported by validator.”);

                           LogValidationResult(validationResults, “Object is not a collection.”, currentTarget, key);
                     }

I’ve also changed testing console app to a number of MSTest TestMethods.

#region Namespace Imports
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.SDC.Common.Validation;
using Microsoft.SDC.Common.Web.WCF;
using Microsoft.VisualStudio.TestTools.UnitTesting;


#endregion
namespace MSCommon.Validation
{
// I have defined an Order class
//      containing an Items property for this. There are four possible cases we can test:


//- Collection is empty, Negated property is false

//- Collection is non-empty, Negated property is false

//- Collection is non-empty, Negated property is true

//- Collection is empty, Negated property is true


       [ TestClass]
        public class CollectionNotEmptyValidatorTests
       {
              [ TestMethod(), CITest ]
               public void InvalidTest_CollectionIsEmpty()
              {
                      // Invalid test – collection is empty
                      var order = NewEmptyOrder();
                      CollectionNotEmptyValidator validator = new CollectionNotEmptyValidator ();

                      ValidationResults results = validator.Validate(order.Items);

                      Assert.IsTrue(!results.IsValid);

                      Debug.WriteLine(results.First().Message);

                      // Output: The collection must not be empty.
              }

              [ TestMethod(), CITest ]
               public void ValidTest_CollectionIsEmpty()
              {
                      // Valid test – collection has items
                      var order = NewEmptyOrder();
                     order.Items.Add( new Order. OrderItem());
                      CollectionNotEmptyValidator validator = new CollectionNotEmptyValidator ();

                      ValidationResults results = validator.Validate(order.Items);

                      Assert.IsTrue(results.IsValid);

                      Debug.WriteLine( “Valid test”);
              }

              [ TestMethod(), CITest ]
               public void NegatedTest_CollectionHasItems()
              {
                      // Invalid test – collection has items (Negated)

                      var order = NewEmptyOrder();
                     order.Items.Add( new Order. OrderItem());
                      CollectionNotEmptyValidator validator = new CollectionNotEmptyValidator (true );

                      ValidationResults results = validator.Validate(order.Items);
                      Assert.IsTrue(!results.IsValid);

                      Debug.WriteLine(results.First().Message);
                      // Output: The collection must be empty.
              }


              [ TestMethod(), CITest ]
               public void NegatedTest_CollectionIsEmpty()
              {
                      // Invalid test – collection has items (Negated)

                      var order = NewEmptyOrder();
                     order.Items.Add( new Order. OrderItem());
                      CollectionNotEmptyValidator validator = new CollectionNotEmptyValidator (true );

                      ValidationResults results = validator.Validate(order.Items);
                      Assert.IsTrue(!results.IsValid);

                      Debug.WriteLine(results.First().Message);
                      // Output: The collection must be empty.
              }


               private static Order NewEmptyOrder()
              {
                      Order order = new Order();

                     order.Items = new Collection<Order .OrderItem >();
                      return order;
              }

              #region Example Classes for tests

               public class Order

              {
                     [ CollectionNotEmptyValidator()]
                      public Collection<OrderItem > Items { get; set; }

                      public bool ValidateItems()

                     {
                            return Items.Count > 0;
                     }

                      public class OrderItem

                     {
                     }
              }

              #endregion //Example Classes for tests
       }
}
I am planning to create derived ContainValidator.