Dario, I have come up with a solution to my problem. What I want is a way to
add or remove rules for a domain object without having to touch it's
ValidationDef<T> implementation. That can not be accomplished by implementing
more than one ValidationDef<T> for a type because only the first one registered
in the configuration is used and the others are ignored. To solve this I came
up with a wrapper for ValidationDef<T> and created some supporting classes.
This together with a IOC container makes the process painless. Here is the
code.
Public Class Foo
Public Property Name As String
Public Property Age As Integer
End Class
Public MustInherit Class Rule(Of T)
Protected _rule As Func(Of T, IConstraintValidatorContext, Boolean)
Public ReadOnly Property Definition As Func(Of T,
IConstraintValidatorContext, Boolean)
Get
Return _rule
End Get
End Property
End Class
Public Class FooRule1
Inherits Rule(Of Foo)
Public Sub New()
_rule = Function(foo, context) As Boolean
context.DisableDefaultError()
context.AddInvalid("FooRule1", "Name")
Return False
End Function
End Sub
End Class
Public Class FooRule2
Inherits Rule(Of Foo)
Public Sub New()
_rule = Function(foo, context) As Boolean
context.DisableDefaultError()
context.AddInvalid("FooRule2", "Name")
Return False
End Function
End Sub
End Class
Public Interface IValidationDef
End Interface
Public Class RuleDef(Of T As Class)
Inherits ValidationDef(Of T)
Implements IValidationDef
Public Sub New(ByVal rules() As Rule(Of T), ByVal configuration As
FluentConfiguration)
rules.ToList.ForEach(Sub(rule) Me.ValidateInstance.By(rule.Definition))
configuration.Register(Me)
End Sub
End Class
Public Class FooDef
Inherits RuleDef(Of Foo)
Public Sub New(ByVal rules() As Rule(Of Foo), ByVal configuration As
FluentConfiguration)
MyBase.New(rules, configuration)
End Sub
End Class
<TestMethod()>
Public Sub RulesWithNHTake3()
Dim _configuration As New FluentConfiguration
_configuration.SetDefaultValidatorMode(ValidatorMode.UseExternal)
Dim _container As New WindsorContainer
_container.Register(Component.For(Of
FluentConfiguration).Instance(_configuration))
_container.AddFacility(Of ArrayFacility).
Register(Component.For(Of Rule(Of Foo)).ImplementedBy(Of FooRule1)).
Register(Component.For(Of Rule(Of Foo)).ImplementedBy(Of FooRule2))
_container.Register(Component.For(Of IValidationDef).ImplementedBy(Of
FooDef))
_container.ResolveAll(Of IValidationDef)()
Dim engine As New ValidatorEngine
engine.Configure(_configuration)
Dim foo As New Entities.Foo With {.Age = 10, .Name = "Bar"}
Dim results = engine.Validate(foo)
Assert.IsTrue(results.Count.Equals(2))
End Sub
----- Original Message -----
From: "Periop IT" <[email protected]>
To: [email protected]
Sent: Monday, December 13, 2010 9:00:01 AM
Subject: Re: NHibernate.Validator Rules Processing
Dario thanks for the quick reply. I realize that this is basically a
constraints engine not so much a business rule engine, however, if I wanted to
add new constraints it a separate class the engine seems to ignore the new
constraints. Only if they are all within the same class do the appear to work
correctly. Here is a simple example of what I mean.
Public Class Foo
Public Property Name As String
Public Property Age As Integer
End Class
Imports NHibernate.Validator.Cfg.Loquacious
Imports Entities
Public Class Rule1
Inherits ValidationDef(Of Foo)
Public Sub New()
Me.ValidateInstance.By(Function(foo, context) As Boolean
context.DisableDefaultError()
context.AddInvalid("HIT", "Age")
Return False
End Function)
Me.ValidateInstance.By(Function(foo, context) As Boolean
context.DisableDefaultError()
context.AddInvalid("HIT2", "Name")
Return False
End Function)
End Sub
End Class
Public Class Rule2
Inherits ValidationDef(Of Foo)
Public Sub New()
Me.ValidateInstance.By(Function(foo, context) As Boolean
context.DisableDefaultError()
context.AddInvalid("HIT3", "Name")
Return False
End Function)
End Sub
End Class
<TestMethod()>
Public Sub RuleTestOne()
Dim _configuration As New FluentConfiguration
_configuration.SetDefaultValidatorMode(ValidatorMode.UseExternal)
_configuration.Register(Of Rules.Rule1, Entities.Foo)()
_configuration.Register(Of Rules.Rule2, Entities.Foo)()
Dim engine As New ValidatorEngine
engine.Configure(_configuration)
Dim foo As New Entities.Foo With {.Age = 10, .Name = "Bar"}
Dim results = engine.Validate(foo)
Assert.IsTrue(results.Count.Equals(3))
End Sub
The test should return 3 and pass but it fails because it returns 2. If I
combing Rules1&2 into a single rule then the test will work.
----- Original Message -----
From: "Dario Quintana" <[email protected]>
To: "NHibernate Contrib - Development Group" <[email protected]>
Sent: Friday, December 10, 2010 8:15:44 AM
Subject: Re: NHibernate.Validator Rules Processing
Hi
NHV is more constraint validation engine than a rule one, once you
define the validation configuration, you have to use it. Maybe you
just missed something in your configuration (and I'm not following it)
Regards
On 9 dic, 17:19, Periop IT <[email protected]> wrote:
> I have been getting ready to use the Validator for a particular domain
> using the ValidatorEngine. What I did to familiarize myself with the
> process of writing rules was to create some simple tests on lets say
> object Foo. Foo has two properties Age and Name. I created a
> validation definition for Foo called Rule1. Rule1 has a one rule
> using the ValidatateInstance Method that always returns false. When I
> run my initial test using the engine it runs as expected. Now if I
> create a second validation definition for Foo in another class called
> Rule2. Like Rule1, Rule2 has a single rule using the ValidateInstance
> Method the always returns false. I create a second test that
> registers both Rule1 and Rule2 to the configuration. When I run the
> test Rule2 never gets called. It would appear that you can only have
> one validation definition for an object. Is this true? Perhaps I
> should not be using Validator for this purpose. Does anyone have any
> advice? Thanks...
--
You received this message because you are subscribed to the Google Groups
"NHibernate Contrib - Development Group" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhcdevs?hl=en.
--
You received this message because you are subscribed to the Google Groups
"NHibernate Contrib - Development Group" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhcdevs?hl=en.
--
You received this message because you are subscribed to the Google Groups
"NHibernate Contrib - Development Group" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhcdevs?hl=en.