I am having an issue casting an entity to a interface to use within a static method. The error I get is a InvalidCastException. I need to perform this cast because I have a static method that needs to take an specific interface definition. I think (though I haven’t tried) that using an abstract class as opposed to an interface might work, but C# doesn’t support inheritance from abstract classes and my entity already inherits from one abstract class.
My model is fairly simple. I have one entity object – MemberStatus – that has an Id, Name and DisplayOrder. It inherits from an Entity abstract class (which inherits from IIdentifiableEntity) and implements the INamedEntity, IOrderedEntity interfaces. Each of these abstract classes or interfaces contains just one property (Id, Name and DisplayOrder).
Here’s my code within my domain project:
public abstract class Entity : IIdentifiableEntity
{
public int Id { get; set; }
}
public interface INamedEntity
{
string Name { get; set; }
}
public interface IOrderedEntity
{
float DisplayOrder { get; set; }
}
public class MemberStatus : Entity, INamedEntity, IOrderedEntity
{
public string Name { get; set; }
public float DisplayOrder { get; set; }
}
public interface IRepository<TEntity>
{
TEntity FindById(int id);
bool InsertOrUpdate(TEntity entity);
//... More methods here
}
Here is my static method (which I want to be able to be use for any IOrderedEntity):
public static void MoveDisplayOrder(IRepository<IOrderedEntity> repository, int id, bool moveUp)
{
var currentStatus = repository.FindById(id);
//...do reordering work
repository.InsertOrUpdate(currentStatus);
}
Within my MVC controller (in my web project), I then have the following:
public class AdminController : Controller
{
private readonly IRepository<MemberStatus> _memberStatusRepository;
public AdminController(IRepository<MemberStatus> memberStatusRepository)
{
_memberStatusRepository = memberStatusRepository;
}
public ActionResult StatusMoveDisplayOrder(int id, bool moveUp)
{
// Code fails on the following line...
MoveDisplayOrder((IRepository<IOrderedEntity>) _memberStatusRepository, id, moveUp);
return RedirectToAction("Index");
}
// Rest of controller code here...
}
The code fails (at run time… it compiles fine) when the controller calls StatusMoveDisplayOrder and it in turn tries to call the static MoveDisplayOrder. All this code was working perfectly until I made the MoveDisplayOrder static and changed the first parameter from IRepository<MemberStatus> to IRepository<IOrderedEntity>. Again, I made that change so that I can call this method on any entity that has a DisplayOrder property (implements IOrderedEntity). What am I doing wrong?
FYI – I am using ninject, in case there is something in there that I need to adjust.
IRepository<MemberStatus> is not anIRepository<IOrderedEntity>even though MemberStatus implements IOrderedEntity. You need to make IRepository a covariant generic interface like this if you really wanted to be able to do the type conversion.http://msdn.microsoft.com/en-us/library/dd997386.aspx
This isn’t possible as written though because IRepository’s methods wouldn’t be able to take the TEntity as a parameter. Instead of casting you can change your static method..