My database has several tables to store devices info. All of them with very similar functionality and fields, but they all have a few specific needs.
For this solution I created a data project, where I wrote database access and Models. My interface for table common fields:
public interface IInstrumento
{ /* Common properties here */ }
My models are declared like this:
public class Motor : IInstrumento
{ /* Model specific properties + interface properties here */ }
This models works and can be used to connect with the database using DbContext.
Then I created a business project includin CRUD repositories. I wrote an interface for this:
public interface IInstrumentoRepository<TModel> where TModel : IInstrumento
{
string Add(TModel obj);
TModel Get(string id);
IQueryable<TModel> GetAll();
int Update(TModel obj);
int Delete(TModel obj);
}
And specific repositories for each model:
public class MotorRepository : IInstrumentoRepository<Motor>
{
private MyContext context = new MyContext();
public string Add(Motor obj) { ... }
/* etc. */
}
All this stuff worked for me. My problem started when I tried to create an abstract controller for this. Since they all share same functionality, the only thing I have to change are the views and the way I create ViewModels, which is something I can do in every subclass.
My abstract controller looks like this:
public abstract class InstrumentosController<T> : Controller
where T : class, IInstrumentoRepository<IInstrumento>
{
protected readonly T repo;
public InstrumentosController(T repo)
{
this.repo = repo;
}
/* Methods might be not abstract */
public abstract IActionResult Index();
/* ... More methods here */
}
When I try to create the controller...
public class MotoresController : InstrumentosController<MotorRepository>
{
public MotoresController(MotorRepository repo)
: base(repo)
{ }
public override IActionResult Index() { ... }
}
... I get a compile error: The type '...MotorRepository' cannot be used as type parameter 'T' in the generic type or method 'InstrumentosController'. There is no implicit reference conversion from 'MotorRepository' to 'IInstrumentoRepository<....Models.IInstrumento>'.
Of course, the Startup class defines every repository so I can use this controllers.
Any suggestion? Thank you all!