Skip to content

Instantly share code, notes, and snippets.

@brianium
Created July 5, 2012 19:19
Show Gist options
  • Save brianium/3055843 to your computer and use it in GitHub Desktop.
Save brianium/3055843 to your computer and use it in GitHub Desktop.
EntityBuilder
void Main()
{
var f = new DogBuilder();
f.GetInstance().Dump();
}
// Define other methods and classes here
public class Dog : Entity<Dog>
{
public string Name {get;set;}
public string Breed {get;set;}
public char Gender {get;set;}
public bool IsFixed {get;set;}
public ICollection<Dog> Puppies {get;set;}
public ICollection<Flea> Fleas {get;set;}
}
public class Flea : Entity<Flea>
{
}
public class Entity<T> : Entity where T: Entity<T>
{
public long Id {get; private set;}
}
public interface Entity
{
}
abstract public class EntityBuilder<T> where T : Entity<T>, new()
{
protected T Instance {get;set;}
public EntityBuilder()
{
Instance = new T();
var props = typeof(T).GetProperties();
foreach(var prop in props)
{
if(IsEntityEnumerable(prop.PropertyType))
SetEntityCollection(GetEntitySet(),prop);
}
}
public virtual T GetInstance()
{
return Instance;
}
protected EntitySet GetEntitySet()
{
var attrs = GetType().GetCustomAttributes(true);
if(attrs.Count() == 0) return null;
return attrs.FirstOrDefault(a => a.GetType() == typeof(EntitySet)) as EntitySet ?? null;
}
protected void SetEntityCollection(EntitySet set, PropertyInfo prop)
{
var setType = set.EnumerableType;
Type[] typeArgs = prop.PropertyType.GetGenericArguments();
var toMake = setType.MakeGenericType(typeArgs);
prop.SetValue(Instance, Activator.CreateInstance(toMake), null);
}
protected bool IsEntityEnumerable(Type t)
{
if(!IsGenericEnumerable(t)) return false;
var genericTypes = t.GetGenericArguments();
foreach(var gt in genericTypes)
{
if(!typeof(Entity).IsAssignableFrom(gt))
return false;
}
return true;
}
protected bool IsGenericEnumerable(Type t)
{
if(!typeof(IEnumerable).IsAssignableFrom(t)) return false;
if(!t.IsGenericType) return false;
return true;
}
}
[EntitySet(typeof(HashSet<>))]
public class DogBuilder : EntityBuilder<Dog>
{
}
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class EntitySet : Attribute
{
public Type EnumerableType {get;private set;}
public EntitySet(Type enumerableType)
{
if(!typeof(IEnumerable).IsAssignableFrom(enumerableType))
throw new ArgumentException("EntitySet must be an enumerable type");
EnumerableType = enumerableType;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment