It's very possible but you either have to not use a common interface or do a lot of casting. Using an interface ...
public interface IRepository
{
public object Get(int id); // or object id
public void Save(object obj);
}
public class CustomerRepository : IRepository
{
public object Get(int id) { // implementation }
public void Save(object obj) { // implementation }
}
This works fine but calling code has to cast objects to the correct type and methods in concrete implementations have to check type and throw exceptions. Direct casting is asking for runtime exceptions so I would avoid this approach.
The approach I would recommend is to not have your repositories implement a common interface. Instead have them implement commonly named methods by convention.
public class CustomerRepository
{
public Customer Get(int id) { // implementation }
public void Save(Customer entity) { // implementation }
}
public class EmployeeRepository
{
public Employee Get(int id) { // implementation }
public void Save(Employee entity) { // implementation }
}
Edited to add: I reread the linked answer. The last full paragraph loses me but I can expand a bit on using DI. In most cases it wouldn't make sense to use DI to inject a "generic" (in this case meaning derived from a common interface) repository. In addition to the common methods, a repository will have entity specific methods such as GetCustomersWithPastDueAccounts
. You could define an ICustomerRepository with that method and have your CustomerRepository implement that. Then you could use dependency injection to inject CustomerRepository at runtime. There's nothing wrong with that, but in my experience it's fairly rare that you would have multiple implementations of a repository so there's little point in doing so.