0

I understand that empty interfaces are likely to be a code smell. I find myself using one, and I am unable to find what the design flaw is.

I have a DBServer abstract class, called Server

public abstract class Server
    {
        protected ICustomerRepository CustomerRepository;
        public string HostName{ get; }

        protected Server(string HostName)
        {
            this.HostName = HostName;
        }

        protected GetCustomers()
        {
            return CustomerRepository.GetCustomers();
        } 
    }

Since I use two DB Engines, say A and B, I have two implemetations.

Implementation for A requires a ICustomerRepository for A, say ACustomerRepository.

However, in order to be able to unit-test the implementation for A, I will use an interface IACustomerRepository and inject the dependency.

The problem is that this interface is empty.

 public interface ICustomerRepository
    {
        string HostName { get; set; }
        IEnumerable<ICustomer> GetCustomers();
    }


public interface IACustomerRepository:ICustomerRepository
{
}

This interface implements the logic to retrive data from the DB for engine A:

class ACustomerRepository : IACustomerRepositoryRepository
{
    public IEnumerable<ICustomer> GetCustomers()
    {
        //Data retrieval logic...
    }
}

This implementation is injected into the Server implementation for A, using Unity:

public class ServerA: Server
    {
        public ServerA (
            string HostName,
            IACustomerRepository ACustomerRepository):
            base(HostName)
        {
            CustomerRepository = ACustomerRepository;
            ACustomerRepository.HostName = HostName;
        }
    }

Unity config:

container.RegisterType<IACustomerRepository, ACustomerRepository>();

I have read about 'marker interfaces', but I am not really sure it applies here.

Could you help me identify the underlying issue, so that I can fix this code smell?

Maxime
  • 1,245
  • 2
  • 14
  • 24
  • 1
    I am not sure I understand. What actually implements `IACustomerRepository`? – maccettura Jul 03 '18 at 14:12
  • @maccettura My bad, I forgot to put it in the question. I have added the implementation. – Maxime Jul 03 '18 at 14:19
  • If `IACustomerRepository` is just `ICustomerRepository` why have `IACustomerRepository` at all? Is it just for dependency injection? In that case you dont really have any other choice unless your IOC container supports per context registrations – maccettura Jul 03 '18 at 14:22
  • I assume the "need" for the marker interface is so that you are able to configure your IoC container. Your container probably supports container.Register("when injected to AServer") - so that just 1 interface is enough. Which IoC container do you use? – Vladi Pavelka Jul 03 '18 at 14:22
  • Looks like unfinished code, for future expansion. Or perhaps someone is keeping to a pattern. Why would it need fixing? –  Jul 03 '18 at 14:22
  • Do you need to change the database engine at runtime? Or have both engines active concurrently in different parts of the app? Or could you simply add an if statement to your registration and register the relevant implementation class for the user's current config? – Jonas Høgh Jul 03 '18 at 14:26
  • @JonasH Multiple servers are used as source, using both engines – Maxime Jul 03 '18 at 14:27
  • @VladimirPavelka I think you gave me a good indication. I use Unity, and your comment made me read about Strategy Design (https://stackoverflow.com/questions/32296209/dependency-injection-unity-conditional-resolving). It might be a way out – Maxime Jul 03 '18 at 14:28

0 Answers0