So today we were working on a new sample project using NHibernate, Ninject and, ASP.Net MVC3 which (as is usually the case at the start of these things) we wanted to be just right. Typically we ended up with a Client type with its expected lists of phone number and email address, in each list none or one of which can be flagged as being the default. We ended up with a class hierarchy like:
public abstract class BaseEntity
{
public virtual int Id { get; set; }
}
public abstract class BaseEmailAddress
{
public virtual string EmailAddress { get; set; }
public virtual bool IsDefault { get; set; }
}
public class ClientEmailAddress
{
private Client client;
public virtual Client Client
{
get { return this.client; }
private set { this.client = value; }
}
}
public class Client : BaseEntity
{
private IList<ClientEmailAddress> emailAddresses = new List<ClientEmailAddress>();
public virtual IList<ClientEmailAddress> EmailAddresses
{
get { return this.emailAddresses; }
private set { this.emailAddresses = value; }
}
}Everything inherits BaseEntity, ClientEmailAddress inherits BaseEmailAddress which implements the EmailAddress and IsDefault properties.
So then we questioned where do we implement the none or one ClientEmailAddress being flagged IsDefault? We decided that we could shadow the IsDefault property in ClientEmailAddress and implement the logic in the setter; if setting my IsDefault property to true then set the IsDefault property of all the other items in my parents ClientEmailAddresses collection. Like this:
public class ClientEmailAddress
{
private Client client;
public virtual Client Client
{
get { return this.client; }
private set { this.client = value; }
}
public new virtual bool IsDefault
{
get { return base.isDefault; }
set
{
if (value && this.client != null)
{
foreach (var clientEmailAddress in this.client.ClientEmailAddresses)
{
clientEmailAddress.IsDefault = false;
}
}
base.isDefault = value;
}
}
}However, NHibernate did not like this very much, complaining the 'IsDefault is already mapped' or similar which got us to thinking whether the IsDefault property belonged on a BaseEmailAddress type? After some debate we can to the conclusion that the IsDefault property is only relevent to the ClientEmailAddress type since it is only in the context of a list of email addresses that being the default email address makes any sense. So we moved the IsDefault property to the relevent class:
public abstract class BaseEmailAddress
{
public virtual string EmailAddress { get; set; }
}
public class ClientEmailAddress
{
private Client client;
public virtual Client Client
{
get { return this.client; }
private set { this.client = value; }
}
private bool isDefault = false;
public virtual bool IsDefault
{
get { return this.isDefault; }
set
{
if (value && this.client != null)
{
foreach (var clientEmailAddress in this.client.ClientEmailAddresses)
{
clientEmailAddress.IsDefault = false;
}
}
this.isDefault = value;
}
}
}
53cce46f-4add-4b84-a6da-6904e7252445|0|.0