A bit new at the Repository Pattern. Trying to build a generic repository that will also handle state changes to derived entities. What I’ve done so far is create a custom attribute to flag the property as one which needs to be upserted.
Attribute:
public class DerivedObjectAttribute : Attribute
{
public enum EntityType
{
REFERENCE,
OBJECT
}
public EntityType DerivedType { get; set; }
}
I define this attribute for any property on which I want to cascade state changes.
Sample Entity:
public class FightingCharacter : BaseEntity
{
public Costume costume { get; set; }
[DerivedObject(DerivedType=DerivedObjectAttribute.EntityType.REFERENCE)]
public SpecialFinish specialFinish { get; set; }
[DerivedObject(DerivedType = DerivedObjectAttribute.EntityType.REFERENCE)]
public List<MoveList> moveList { get; set; }
}
So for this class, the costume property would not need to cascade, but the specialFinish and moveList properties should.
Then in my repository:
public class DataRepository<T> : IRepository<T> where T : BaseEntity {
private void TryDerivedUpsert(T entity)
{
Type type = entity.GetType();
PropertyInfo[] piList = type.GetProperties();
foreach (PropertyInfo pi in piList)
{
foreach (DerivedObjectAttribute attr in pi.GetCustomAttributes(typeof(DerivedObjectAttribute), false))
{
// What to do here?
}
}
}
}
In the innermost loop, I’m able to pinpoint DerivedObjectAttributes without any problem. The question is: how do I obtain the Type and Value of the object, then upsert it? In other words: if property pi is flagged to cascade changes, create a repo cast to the appropriate Entity, and Upsert it. E.G.:
DataRepository<EntityType> repo = new DataRepository<EntityType> ();
repo.Upsert(property as EntityType);
Does that make sense? Or am I going about generic repo entirely the wrong way? If it does make sense (I’ll be surprised), how to do it? (The examples listed here are just examples, BTW. I’m still architecting and have no EF classes at all yet.)
You could get the value with
pi.GetValue(entity, null), and create the generic repository (Activate.CreateInstance) for the property type (from pi), but you will have to do a lot of reflection.In this case you should think about dropping the classic generic repository idea (separate repository per type) and use something like an extended
DbContext, that can handle all types.If you have a disconnected scenario (WCF), the main problem will be EF itself, because you have to replicate all changes to nested lists on the server side and manually change the EntityState.