piab, validation, ruleset, and config file

Topics: Policy Injection Application Block, Validation Application Block
Mar 19, 2009 at 9:26 PM
I would like to have piab force a validation ruleset to run when an instance property is set to a value.  That probably isn't properly phrased because I am having trouble completely understanding the scope of piab and validation used together.  Additionally, I would like all my rules established in the config file.  All of the samples I have found showing piab and validation working together involve attributed conditions.

Basically, I find that I can create a validation rule in the config file:

<

 

validation>
<
type defaultRuleset="firstNamePresent" assemblyName="business, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="business.IPerson">
<
ruleset name="firstNamePresent">
<
properties>
<
property name="first">
<
validator negated="false" messageTemplate="firstNamePresent rule says can't be null" messageTemplateResourceName="" messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Not Null Validator" />
</
property>
</
properties>
</
ruleset>
</
type>
</
validation>
<
policyInjection>
<
policies>
<
add name="business module">
<
matchingRules>
<
add match="business" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.AssemblyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Assembly Matching Rule" />
</
matchingRules>
<
handlers>
<
add ruleSet="validInstance" specificationSource="Both" order="0" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="Validation Handler" />
</
handlers>
</
add>
</
policies>
</
policyInjection>

 

Then I have an interface from which my real instance descends:

public interface IPerson
{
string first { get; set; }
string middle { get; set; }
string last { get; set; }
void setName([StringLengthValidator(2,3, MessageTemplate="IPerson attribute says firstName can't be null") ]string firstName, string middleName, string lastName);

}

in the following code, the facade call to validate the entire object with the default rule results in a message that the firstName can't be null.  However, setting the value null does not result in an exception.  My question is how can I use rules in the config file to do the same thing the facade call is doing.

namespace business
{
 public class person : IPerson
 {
  string _first;
  public string first { get { return _first; } set { _first = value; } }
  string _middle;
  public string middle { get { return _middle; } set { _middle = value; } }
  string _last;
  public string last { get { return _last; } set { _last = value; } }

  public person()
  {
  }

  public void setName(string firstName, string middleName, string lastName)
  {
   first = firstName;
   middle = middleName;
   last = lastName;
  }
         }
}


Mar 20, 2009 at 3:48 AM
AFAIK, only WCF supports parameter validation. One thing that you can do is to wrap the parameters of the setName method into a class, add validation to the properties of that class and use the piab to validate the class.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
Mar 20, 2009 at 12:17 PM
Valiant:

Thank you very much for your rapid response.

Oddly enough the parameter check is caught by piab.  I have copied all the application source below and will be very happy to email you a copy if you wish. 

At least I assume it's piab because the call to setName is throwing an exception.  What doesn't seem to work is the firstNamePresent rule in the config file.  The rule disallows null, but no exception is thrown when I set the property to null.  I have tried setting the rule on the interface type and the instance type, but neither seems to work.

jwL

using

 

Microsoft.Practices.EnterpriseLibrary.Common;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

 

using

 

Microsoft.Practices.EnterpriseLibrary.PolicyInjection;

 

using

 

Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers;

 

using

 

Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Validation;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

 

using

 

Microsoft.Practices.Unity;

 

using

 

Microsoft.Practices.Unity.Configuration;

 

using

 

Microsoft.Practices.Unity.InterceptionExtension.Configuration;

 

using

 

Microsoft.Practices.Unity.InterceptionExtension;

 

using

 

Microsoft.VisualStudio.TestTools.UnitTesting;

 

using

 

System;

 

using

 

System.Configuration;

 

using

 

System.Diagnostics;

 

using

 

System.Resources;

 

using

 

System.Text;

 

using

 

System.Windows.Forms;

 

using

 

business;

 

namespace

 

simpleValidationWUnityExampleTest

 

{

 

 

 

/// <summary>

 

 

///This is a test class for personTest and is intended

 

 

///to contain all personTest Unit Tests

 

 

///</summary>

 

[

TestClass()]

 

 

public class personTest

 

{

 

private TestContext testContextInstance;

 

 

/// <summary>

 

 

///Gets or sets the test context which provides

 

 

///information about and functionality for the current test run.

 

 

///</summary>

 

 

public TestContext TestContext

 

{

 

get

 

{

 

return testContextInstance;

 

}

 

set

 

{

testContextInstance =

value;

 

}

}

#region

 

Additional test attributes

 

 

//

 

 

//You can use the following additional attributes as you write your tests:

 

 

//

 

 

//Use ClassInitialize to run code before running the first test in the class

 

 

//[ClassInitialize()]

 

 

//public static void MyClassInitialize(TestContext testContext)

 

 

//{

 

 

//}

 

 

//

 

 

//Use ClassCleanup to run code after all tests in a class have run

 

 

//[ClassCleanup()]

 

 

//public static void MyClassCleanup()

 

 

//{

 

 

//}

 

 

//

 

 

//Use TestInitialize to run code before running each test

 

 

//[TestInitialize()]

 

 

//public void MyTestInitialize()

 

 

//{

 

 

//}

 

 

//

 

 

//Use TestCleanup to run code after each test has run

 

 

//[TestCleanup()]

 

 

//public void MyTestCleanup()

 

 

//{

 

 

//}

 

 

//

 

#endregion

 

 

/// <summary>

 

 

///A test for setName

 

 

///</summary>

 

[

TestMethod()]

 

 

public void setNameTest()

 

{

 

//create empty object

 

 

//IPerson target = new person();

 

 

IPerson target = PolicyInjection.Create<person, IPerson>();

 

 

//establish the person's name

 

 

try

 

{

target.first =

null;

 

}

 

catch (Exception exc)

 

{

System.Windows.Forms.

MessageBox.Show("EXCEPTION...target.first = null: " + @"\n\n" + exc.Message + @"\n\n" + exc.StackTrace);

 

}

 

//determine if the person object contains valid data

 

 

Validator<person> validator = ValidationFactory.CreateValidator<person>();

 

 

//apply a set of validation rules to person's data

 

 

ValidationResults results = Validation.Validate(target);

 

 

if (!results.IsValid)

 

 

foreach (ValidationResult result in results)

 

{

System.Windows.Forms.

MessageBox.Show("FACADE...target.first = null: " + @"\n\n" + result.Message);

 

}

 

//establish the person's name

 

 

try

 

{

target.setName(

null, null, null);

 

}

 

catch (Exception exc)

 

{

System.Windows.Forms.

MessageBox.Show("EXCEPTION...target.setName(null, null, null): " + @"\n\n" + exc.Message + @"\n\n" + exc.StackTrace);

 

}

 

//determine if the person object contains valid data

 

validator =

ValidationFactory.CreateValidator<person>();

 

 

//apply a set of validation rules to person's data

 

results =

Validation.Validate(target);

 

 

if (!results.IsValid)

 

 

foreach (ValidationResult result in results)

 

{

System.Windows.Forms.

MessageBox.Show("FACADE...target.setName(null, null, null): " + @"\n\n" + result.Message);

 

}

}

}

}

-----------------------------

using

 

System;

 

using

 

System.Collections.Generic;

 

using

 

System.Diagnostics;

 

using

 

System.Linq;

 

using

 

System.Reflection;

 

using

 

System.Resources;

 

using

 

System.Text;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Common;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

 

using

 

Microsoft.Practices.EnterpriseLibrary.PolicyInjection;

 

using

 

Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Validation;

 

using

 

Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

 

using

 

Microsoft.Practices.Unity;

 

namespace

 

business

 

{

 

public class person : IPerson

 

{

 

string _first;

 

 

public string first { get { return _first; } set { _first = value; } }

 

 

string _middle;

 

 

public string middle { get { return _middle; } set { _middle = value; } }

 

 

string _last;

 

 

public string last { get { return _last; } set { _last = value; } }

 

 

ResourceManager _resourceManager;

 

 

public ResourceManager resourceManager

 

{

 

get

 

{

 

if (_resourceManager == null)

 

_resourceManager =

new ResourceManager("business.personResource", Assembly.GetExecutingAssembly());

 

 

string astring = _resourceManager.GetString(person.errorMessageNamesClass.acceptedNull);

 

 

return _resourceManager;

 

}

}

 

/// <summary>

 

 

/// Return an empty instance.

 

 

/// </summary>

 

 

public person()

 

{

}

 

public void setName(string firstName, string middleName, string lastName)

 

{

first = firstName;

middle = middleName;

last = lastName;

}

#region

 

resourceFileItemNames

 

 

public static class errorMessageNamesClass

 

{

 

static errorMessageNamesClass(){}

 

 

public static string acceptedNull { get { return "acceptedNull"; } }

 

}

#endregion

}

 

public interface IPerson

 

{

 

string first { get; set; }

 

 

string middle { get; set; }

 

 

string last { get; set; }

 

 

void setName([StringLengthValidator(2,3, MessageTemplate="IPerson attribute says firstName can't be null") ]string firstName, string middleName, string lastName);

 

}

}

-------------------------

<?

 

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

 

<

 

configuration>

 

<

 

configSections>

 

<

 

section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

 

<

 

section name="policyInjection" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration.PolicyInjectionSettings, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

 

<

 

section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

 

<!--

 

<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />-->

 

</

 

configSections>

 

<

 

validation>

 

<

 

type defaultRuleset="firstNamePresent" assemblyName="business, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

 

 

 

name="business.IPerson">

 

<

 

ruleset name="firstNamePresent">

 

<

 

properties>

 

<

 

property name="first">

 

<

 

validator negated="false" messageTemplate="firstNamePresent rule says can't be null"

 

 

 

messageTemplateResourceName="" messageTemplateResourceType=""

 

 

 

tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

 

 

 

name="Not Null Validator" />

 

</

 

property>

 

</

 

properties>

 

</

 

ruleset>

 

</

 

type>

 

</

 

validation>

 

<

 

policyInjection>

 

<

 

policies>

 

<

 

add name="business module">

 

<

 

matchingRules>

 

<

 

add match="business" type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.AssemblyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

 

 

 

name="Assembly Matching Rule" />

 

</

 

matchingRules>

 

<

 

handlers>

 

<

 

add ruleSet="validInstance" specificationSource="Both" order="0"

 

 

 

type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

 

 

 

name="Validation Handler" />

 

</

 

handlers>

 

</

 

add>

 

</

 

policies>

 

</

 

policyInjection>

 

</

 

configuration>

 



Mar 20, 2009 at 3:05 PM
Yes. that would be great. can you send me a copy.

Valiant Dudan
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com