Validator Patch To Expose Property and Entity in IConstraintValidatorContext

45 views
Skip to first unread message

Raymond

unread,
Aug 8, 2011, 7:10:26 PM8/8/11
to NHibernate Contrib - Development Group
Hi all,

I am attempting to implement a NotNullNotDeActivated custom validator
in my project. It will extend the NotNull validator and add some logic
for checking an active flag that my entities implement.
It will replace most usages of the NotNull validator throughout my
project and should provide a nice way of enforcing deactivation
through my system.

My problem is that I cannot see how I can get access to to the entity
when I write a property validator (i.e.
[AttributeUsage(AttributeTargets.Property)]).
I need the entity so that I can allow deactivated entities to
reference other deactivated entities. e.g. If we have Organisation and
Person, the Person is only allowed to be deactivated if the
organisation is deactivated too.

I think the most logical place to provide access to the entity is in
the IConstraintValidatorContext passed in when IsValid is implemented,
since it gives the validation code more context.
I have implemented the changes in my checkout of svn trunk and created
a patch using Tortoise svn (at the end of this post).

Can one of the developers please see if these changes make sense and
if I have implemented them correctly with regard to the project as a
whole and if the changes can be added to the project.
The patch also provides access to the property to make the context
more complete.

Is there any documentation available on how to set up the testing
environment?
The tests keep trying to connect to a database and failing.

Regards,
Raymond Kortas


Index: NHibernate.Validator.Tests/ConstraintContext/
ConstraintValidatorContextFixture.cs
===================================================================
--- NHibernate.Validator.Tests/ConstraintContext/
ConstraintValidatorContextFixture.cs (revision 1686)
+++ NHibernate.Validator.Tests/ConstraintContext/
ConstraintValidatorContextFixture.cs (working copy)
@@ -12,7 +12,7 @@
[SetUp]
public void OnSetup()
{
- c = new ConstraintValidatorContext("SomeProperty", "This is
Default Message");
+ c = new ConstraintValidatorContext(null, "SomeProperty", "This is
Default Message");
}

#endregion
Index: NHibernate.Validator.Tests/ConstraintContextMock.cs
===================================================================
--- NHibernate.Validator.Tests/ConstraintContextMock.cs (revision
1686)
+++ NHibernate.Validator.Tests/ConstraintContextMock.cs (working copy)
@@ -33,6 +33,15 @@
throw new NotImplementedException();
}

+ public string PropertyName
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public object Entity
+ {
+ get { throw new NotImplementedException(); }
+ }
#endregion
}
}
\ No newline at end of file
Index: NHibernate.Validator/Engine/ClassValidator.cs
===================================================================
--- NHibernate.Validator/Engine/ClassValidator.cs (revision 1686)
+++ NHibernate.Validator/Engine/ClassValidator.cs (working copy)
@@ -306,7 +306,7 @@
{
return from validatorDef in entityValidators.Where(ev =>
IsValidationNeededByTags(activeTags, ev.Tags))
let validator = validatorDef.Validator
- let constraintContext = new ConstraintValidatorContext(null,
defaultInterpolator.GetAttributeMessage(validator))
+ let constraintContext = new ConstraintValidatorContext(entity,
null, defaultInterpolator.GetAttributeMessage(validator))
where !validator.IsValid(entity, constraintContext)
select new InvalidMessageTransformer(constraintContext,
activeTags, entityType, null, entity, entity, validatorDef,
defaultInterpolator, userInterpolator)
into invalidMessageTransformer
@@ -694,7 +694,7 @@
let value = TypeUtils.GetMemberValue(entity, member)
where IsValidationNeededByTags(activeTags,
mtv.ValidatorDef.Tags) && NHibernateHelper.IsInitialized(value)
let validator = mtv.ValidatorDef.Validator
- let constraintContext = new
ConstraintValidatorContext(member.Name,
defaultInterpolator.GetAttributeMessage(validator))
+ let constraintContext = new ConstraintValidatorContext(entity,
member.Name, defaultInterpolator.GetAttributeMessage(validator))
where !validator.IsValid(value, constraintContext)
from invalidValue in new
InvalidMessageTransformer(constraintContext, activeTags, entityType,
member.Name, value, entity, mtv.ValidatorDef, defaultInterpolator,
userInterpolator).Transform()
select invalidValue;
@@ -712,7 +712,7 @@
return from member in memberValidators
let validator = member.ValidatorDef.Validator
let constraintContext =
- new ConstraintValidatorContext(propertyName,
defaultInterpolator.GetAttributeMessage(validator))
+ new ConstraintValidatorContext(null, propertyName,
defaultInterpolator.GetAttributeMessage(validator))
where !validator.IsValid(value, constraintContext)
from invalidValue in
new InvalidMessageTransformer(constraintContext,
activeTags, entityType, propertyName, value, null,
Index: NHibernate.Validator/Engine/ConstraintValidatorContext.cs
===================================================================
--- NHibernate.Validator/Engine/ConstraintValidatorContext.cs
(revision 1686)
+++ NHibernate.Validator/Engine/ConstraintValidatorContext.cs (working
copy)
@@ -12,14 +12,16 @@
private readonly IList<InvalidMessage> invalidValues = new
List<InvalidMessage>();
private readonly string messageAttribute;
private readonly string propertyName;
+ private readonly object entity;
private bool isDisabledDefaultError;

- public ConstraintValidatorContext(string propertyName, string
messageAttribute)
+ public ConstraintValidatorContext(object entity, string
propertyName, string messageAttribute)
{
if (messageAttribute == null) throw new
ArgumentNullException("messageAttribute");

+ this.entity = entity;
this.propertyName = propertyName; //can be null when using Entity-
Validation
- this.messageAttribute = messageAttribute;
+ this.messageAttribute = messageAttribute; //can be null when
getting potential invalid values
}

public bool IsDefaultValidatorEnabled
@@ -68,6 +70,15 @@
AddInvalid(message, member.Name);
}

+ public string PropertyName
+ {
+ get { return propertyName; }
+ }
+
+ public object Entity
+ {
+ get { return entity; }
+ }
#endregion
}

Index: NHibernate.Validator/Engine/IConstraintValidatorContext.cs
===================================================================
--- NHibernate.Validator/Engine/IConstraintValidatorContext.cs
(revision 1686)
+++ NHibernate.Validator/Engine/IConstraintValidatorContext.cs
(working copy)
@@ -14,5 +14,15 @@
void AddInvalid(string message, string property);

void AddInvalid<TEntity, TProperty>(string message,
Expression<Func<TEntity, TProperty>> property);
+
+ /// <summary>
+ /// The name of the property being validated, if available,
otherwise null.
+ /// </summary>
+ string PropertyName { get; }
+
+ /// <summary>
+ /// The entity being validated, if available otherwise null.
+ /// </summary>
+ object Entity { get; }
}
}
Reply all
Reply to author
Forward
0 new messages