You have the chance to change my world (=my code)
public abstract class EntityBase
{
protected StringBuilder m_validationErrors;
public string ValidationErrors
{
get
{
return m_validationErrors.ToString();
}
}
public bool IsValid(Enum field)
{
Validate(field);
return (m_validationErrors.Length == 0);
}
protected abstract void Validate(Enum field);
// Some other code…
}
{
[Flags]
public enum Fields
{
ID = 0x01,
Description = 0x02
}
public int? ID = null; // In the real class, it’s not like this…
public string Description = null; // In the real class, it’s not like this…
public bool IsValid(Fields field)
{
return base.IsValid(field);
}
protected override void Validate(Enum field)
{
if (!(field is Fields))
throw new ArgumentException(this.GetType().Name + “.Validate method must get Area.Fields as parameter”);
Fields f = (Fields)field;
m_validationErrors = new StringBuilder(50);
if (((f & Fields.ID) != 0) &&
ID == null)
{
m_validationErrors.Append(“ID property must be set.” + Environment.NewLine);
}
if (((f & Fields.Description) != 0) &&
Description == null)
{
m_validationErrors.Append(“Description property must be set.” + Environment.NewLine);
}
}
}
Area a = new Area();
//a.ID = 1;
//a.Description = “oren”;
if (!a.IsValid(Area.Fields.ID | Area.Fields.Description))
Console.WriteLine(“Errors: “ + a.ValidationErrors);
else
Console.WriteLine(“a is valid”);
a.IsValid method is a “strongly typed” method which will get Area.Fields as parameter so I’m quite(not entirely, see problem (1)) happy. The catch is when I’m starting to work with multiple Area entities.
3). Declaring my generic EntityCollection class:
public class EntityCollection<ENT> : List<ENT>
where ENT : EntityBase
{
protected StringBuilder m_validationErrors;
//OREN NOTE: “problematic” code number (2) – I want to get Area.Fields as parameter if I’m declaring EntityCollection<Area>
public bool IsValid(Enum field)
{
m_validationErrors = new StringBuilder(Count * 50);
int counter = 0;
this.ForEach(delegate(ENT e)
{
if (!e.IsValid(field))
{
m_validationErrors.AppendFormat(“Index in list: {0}.{2}Errors: {1}{2}”,
counter,
e.ValidationErrors,
Environment.NewLine);
}
counter++;
});
return (m_validationErrors.Length == 0);
}
public string ValidationErrors
{
get { return m_validationErrors.ToString(); }
}
}
Here is a quick usage for this EntityCollection class:
EntityCollection<Area> areas = new EntityCollection<Area>();
Area a1 = new Area();
a1.ID = 5;
Area a2 = new Area();
a2.Description = “orennnnn”;
Area a3 = new Area();
a3.ID = 1;
areas.Add(a1);
areas.Add(a2);
areas.Add(a3);
if (!areas.IsValid(Area.Fields.Description))
Console.WriteLine(“areas Errors: “ + areas.ValidationErrors);
else
Console.WriteLine(“areas is valid”);
areas.IsValid accept Enum as parameters, this is quite shitty because in my ideal world it would accept only Area.Fields as parameter.
The solution I found at the moment is to inherit from EntityCollection and add the check there, something like:
public class Areas : EntityCollection<Area>
{
public bool IsValid(Area.Fields field)
{
m_validationErrors = new StringBuilder(Count * 50);
int counter = 0;
this.ForEach(delegate(Area a)
{
if (!a.IsValid(field))
{
m_validationErrors.AppendFormat(“Index in list: {0}.{2}Errors: {1}{2}”,
counter,
a.ValidationErrors,
Environment.NewLine);
}
counter++;
});
return (m_validationErrors.Length == 0);
}
}
I can always check the integrity of the collection via outside delegate & ForEach method, but I want the collection to verify its inner entities without my help. This is why I need your advice – what do YOU suggest in order to handle this more nicely ? Am I doing something totally wrong ?