One More Stab at Entity Design

Ok all you mvc nuts, I’m back for another attempt. What I’d like to do, rather than toss a bunch of code up and ask ten zillion questions, is take it one step at a time, introducing concepts as I need them, then ask questions based on that iteration. Please comment on my approach and questions, and tell me if I am on the right track or not. If not, put me on the correct path.

First, I want to concentrate on an aggregate root. The basic definition is below:


public class Forum
{
 
public virtual int Id { get; protected set; }
public virtual int Sequence { get; set; }
public virtual string Title { get; protected set; }
public virtual string Description { get; set; }
public virtual bool Moderated { get; set; }
public virtual bool Enabled { get; set; }
public virtual bool Visible { get; set; }
 
public virtual SetTitle(string title)
{
if (string.IsNullOrEmpty(title) || string.IsNullOrWhiteSpace(title))
throw new Exception("Title is invalid!");
Title = title.Trim();
}
 
public Forum(string title)
{
SetTitle(title);
}
 
protected Forum() {}
 
}

This is nice and simple. Next, I wanted to add the moderator collection. Before I could do that, I needed a moderator entity, listed below:


public class Moderator
{
 
public virtual int Id { get; protected set; }
public virtual string Username { get; protected set; }
 
public Moderator(string username)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrWhiteSpace(username))
throw new Exception("Username is invalid!");
Username = username.Trim();
}
 
protected Moderator() {}
 
}

Now to add it to the forum class:


public class Forum
{
 
private IList<Moderator> moderators = new List<Moderator>();
public virtual IEnumerable<Moderator> Moderators { get { return moderators; } }
 
public virtual void AddModerator(Moderator mod)
{
// minus null checks...
if (!moderators.Contains(mod)) moderators.Add(mod);
}
 
public virtual void RemoveModerator(Moderator mod)
{
// minus null checks...
if (moderators.Contains(mod)) moderators.Remove(mod);
}
 
public virtual bool ContainsModerator(Moderator mod)
{
return moderators.Any(x => x == mod);
}
 
public virtual int Id { get; protected set; }
public virtual int Sequence { get; set; }
public virtual string Title { get; protected set; }
public virtual string Description { get; set; }
public virtual bool Moderated { get; set; }
public virtual bool Enabled { get; set; }
public virtual bool Visible { get; set; }
 
public virtual SetTitle(string title)
{
if (string.IsNullOrEmpty(title) || string.IsNullOrWhiteSpace(title))
throw new Exception("Title is invalid!");
Title = title.Trim();
}
 
public Forum(string title)
{
SetTitle(title);
}
 
protected Forum() {}
 
}

So far, so good. Everything makes sense. Next I wanted to add support for subforums. This means the entity will be self referencing. Look at the result below and answer the first batch of questions:


public class Forum
{
 
private IList<Forum> children = new List<Forum>();
public virtual IEnumerable<Forum> Children { get { return children; } }
 
public virtual void AddChild(Forum child)
{
// minus null checks and self checks...
if (!children.Contains(child)) children.Add(child);
}
 
public virtual void RemoveChild(Forum child)
{
// minus null checks and self checks...
if (children.Contains(child)) children.Remove(child);
}
 
public virtual bool ContainsForum(Forum child)
{
return children.Any(x => x == child);
}
 
private IList<Moderator> moderators = new List<Moderator>();
public virtual IEnumerable<Moderator> Moderators { get { return moderators; } }
 
public virtual void AddModerator(Moderator mod)
{
// minus null checks...
if (!moderators.Contains(mod)) moderators.Add(mod);
}
 
public virtual void RemoveModerator(Moderator mod)
{
// minus null checks...
if (moderators.Contains(mod)) moderators.Remove(mod);
}
 
public virtual bool ContainsModerator(Moderator mod)
{
return moderators.Any(x => x == mod);
}
 
public virtual int Id { get; protected set; }
public virtual int Sequence { get; set; }
public virtual string Title { get; protected set; }
public virtual string Description { get; set; }
public virtual bool Moderated { get; set; }
public virtual bool Enabled { get; set; }
public virtual bool Visible { get; set; }
 
public virtual SetTitle(string title)
{
if (string.IsNullOrEmpty(title) || string.IsNullOrWhiteSpace(title))
throw new Exception("Title is invalid!");
Title = title.Trim();
}
 
public Forum(string title)
{
SetTitle(title);
}
 
protected Forum() {}
 
}

So here are the questions based on this so far:

  1. Do I need to include parent forum id’s as private vars?

  2. Do I need to include parent forum reference objects?

  3. Typically, I’ll have a username available for testing against moderators (the current IPrincipal). However, the entity is set to test against a moderator entity. Testing against “new Moderator(username)” shouldn’t work since the two won’t equate (the Id is different). Should I look up the moderator record (if one exists) beforehand, or simply add a “ContainsModeratorNamed(string username)” method to the entity?

Thanks.