Limit collection count

Limit collection count

Old forum URL: forums.lhotka.net/forums/t/12828.aspx


Mr X posted on Monday, February 09, 2015

I am trying to write a reusable business rule that would take an editable collection property and an int value and add a broken rule to my root if the count of the collection is greater than the value.

So far, I have written the following business rule but I was hoping you can help me optimize it. Somehow it doesn't feel pretty. I would rather specify the type of the collection which is specified when the property is registered than that of the item.  All I really need to get out of all this is the count of the collection (regardless of the item type).

I am using CSLA 4.3.12

Thanks

 

public class CollectionMaxCountRule<C> : PropertyRule

{

private int MaxCount { get; set; }

 

public CollectionMaxCountRule(IPropertyInfo primaryProperty, int maxCount): base(primaryProperty)

      {

MaxCount = maxCount;

PrimaryProperty = primaryProperty;

InputProperties = new List<IPropertyInfo>() { primaryProperty };

AffectedProperties.Add(primaryProperty);

 

}

 

protected override void Execute(RuleContext context)

{

ICollection<C> _list = (ICollection<C>)context.InputPropertyValues[PrimaryProperty];

 

 

if (_list.Count > MaxCount)

context.AddErrorResult(PrimaryProperty, string.Format("{0} {1}", ResourceFiles.LibraryResources.CollectionMaxCountRule_Error_MaxCount, MaxCount.ToString()));

}

}

 

 It is added using the following:

 

BusinessRules.AddRule(

 

new CollectionMaxCountRule<CostEstimate>(CostEstimateCollectionProperty, int.Parse(ConfigurationManager.AppSettings["MaxCostEstimateCount"])));

 

ajj3085 replied on Monday, February 09, 2015

The rule looks fine to me, although you could just use the non-generic ICollection (or even IList) if all you're after is the count property. 

In order for the rule to run though you'll have to put it in the parent and manually run the rule in the OnChildChanged override.

Mr X replied on Monday, February 09, 2015

Thank you Andy. You are right the ICollection and IList do work.  I was missing the property reference in my class.

JonnyBee replied on Tuesday, February 10, 2015

Hi,

You could also consider to add generic constraint to the primaryProperty (will give you better typecheck that the property and rule have the same generic constraint) and simplify the rule - just a little bit. And you do NOT have to add PrimaryProperty to AffectedProperties in order to set error result if you use the method that does not take a propertyInfo as parameter (and implicitly defaults to PrimaryProperty)

I try to not use the InputProperties when dealing with list/child lists so my preference would be like this:

public class CollectionMaxCountRule<T> : PropertyRule
{
    private int MaxCount { getset; }
 
    public CollectionMaxCountRule(PropertyInfo<T> primaryProperty, int maxCount)
        : base(primaryProperty)
    {
        MaxCount = maxCount;
    }
 
    protected override void Execute(RuleContext context)
    {
        var list = (ICollection<T>)ReadProperty(context.Target, PrimaryProperty);
 
        if (list.Count > MaxCount)
            context.AddErrorResult(string.Format("{0} {1}", "custom error message", MaxCount));
    }
}

Mr X replied on Tuesday, February 10, 2015

Thanks JonnyBee. I did as you suggested which is very helpful to validate the property type with the rule. However, I wasn't able to use

 var list = (ICollection<T>)ReadProperty(context.Target, PrimaryProperty);

because T is the type of the collection and not that of its children.

I simply changed it to:

  var list = (ICollection)ReadProperty(context.Target, PrimaryProperty); 

Copyright (c) Marimer LLC