Consider the following code:
public abstract class RepositoryBase<T> where T : class
{
#region Members
private MyContext dataContext;
private readonly IDbSet<T> dbset;
#endregion
protected RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get; private set;
}
protected MyContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
}
public virtual void Delete(T entity)
{
dbset.Remove(entity);
}
I would like to replace the Delete method with the one below, since I would prefer to simply set a Deleted field to true in my object to indicated that it is deleted, instead of really deleting it.
public virtual void Delete(T entity)
{
entity.Deleted = true;
dbset.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
}
I am using POCO entities and the Deleted property exists in all of them. However, in the code above entity is of type T, and T “doesn’t know” that there is a Deleted property in all objects it can represent. What is the most elegant way to solve this?
By the way, I would like to access other fields (DateCreated, CreatedBy, DateModified and ModifiedBy) in a similar way in my abstract class.
UPDATE: I tried both the interface and the Abstract class solution, which seemed good at first, but then I got the following error message in both cases when compiling:
Error 11 The type ‘MyProject.Domain.Person’ cannot be used as type parameter ‘T’ in the generic type or method ‘MyProject.Data.Infrastructure.RepositoryBase’. There is no implicit reference conversion from ‘MyProject.Domain.Person’ to ‘MyProject.Domain.AbstractEntity’.
And here is the code the error message is referring to:
namespace MyProject.Data
{
public class PersonRepository : RepositoryBase<Person>, IPersonRepository
{
public PersonRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
}
}
public interface IPersonRepository : IRepository<Person>
{
}
}
Update 2:
I finally got it to work with the solution proposed by SLaks. I used an interface, and I modified the template generating all the POCO entities so that they would all derive from the following IEntity interface:
namespace MyProject.Domain
{
public interface IEntity
{
System.DateTime CreatedDate
{
get;
set;
}
string CreatedBy
{
get;
set;
}
System.DateTime ModifiedDate
{
get;
set;
}
string ModifiedBy
{
get;
set;
}
bool Deleted
{
get;
set;
}
}
}
Using an abstract entity class would be more complicated, since then all the properties in the abstract class would have to be overridden in the entity classes.
You should create an interface with
Deletedand other properties and implement it in your entity classes.You can then constrain the generic type parameter to implement the interface.