jeudi 27 octobre 2016

Using Autofac to switch a concrete implemetation of an abstract factory

I am humbling with a problem related to AutoFac and the the abstract factory pattern. My Example is a a service to use an IRepositoryFactory to create a Repository based on JSON or InMemory related to the user input.

// Abstract Factory
public interface IRepositoryFactory{
    IRepository Create(string databaseIdentifier);
}

// JSON
public class JsonRepositoryFactory{
    public IRepository Create(string databaseIdentifier){
        return new JsonRepository(databaseIdentifier); 
    }
}

// InMemory
public class MemoryRepository{
    public IRepository Create(string databaseIdentifier){
        return new MemoryRepository(databaseIdentifier);
    }
}

The Service should pull the Factory by Constructor Injection.

public interface IShopService{
     public string Name {get;}
} 

public class BeerShop : IShopService {
     public string Name {get; private set;}
     private readonly IRepository _repository;

     public BeerShop(IRepositoryFactory repositoryFactory){
         Name = "beershop";
         _repository = repositoryFactory.Create(Name);
     } 
}

So far I am good with this. But the initialization is not my favorite.

var builder = new ContainerBuilder();
var userInput = ReadInput();

if(userInput = "json")
    builder.RegisterType<IRepositoryFactory>().As<JsonRepositoryFactory>();
else
    builder.RegisterType<IRepositoryFactory>().As<MemoryRepositoryFactory>();

builder.RegisterType<IShopService>.As<BeerShop>();

var container = builder.build();

[...]    

var service = container.Resolve<IShoptService>();
// and so on ...

Is this the right approach to solve it? I am not convinced by my own design because it forces the user input before the initialization of the container. What if the user has to change the Repository while runtime? Is the abstract factory pattern the right tool to solve this problem?

Aucun commentaire:

Enregistrer un commentaire