Search code examples
simple-injector

How to use simple-injector with multiple projects and pass to resolve the dependencies


I have 4 projects in my solution, 1. MyApp.UI (MVC) 2. MyApp.Core (ClassLibrary) 3. MyApp.Data (ClassLibrary with EF implementation) and 4. MyApp.Tests

In my Data project I have 4 repository implementations and all 4 repositories are implemented IRepositoryBase interface and their own repository interface Example,

public class RepositoryA: IRepositoryBase, IRepositoryA
{
.....
}
public class RepositoryB: IRepositoryBase, IRepositoryB
{
.....
}

Now in my Data project I want to create abstract Repository Factory which returns the concrete implementations of corresponding repository interfaces and this class used only inside MyApp.Data project, For example RepositoryFactory.GetRepository<IRepositoryA>() must returns instance of RepositoryA class or RepositoryFactory.GetRepository<IRepositoryB>() must returns instance of RepositoryB class

My concerns are ,

  1. How I can achieve this ? I want to use RepositoryFactory to get the Repository implementations only inside MyApp.Data project.

  2. Since my UI (MVC) application already doing the boot strap do i need to pass the container to MyApp.Data project or Data project need its own container registration logic?.

  3. I also want to test my MyApp.Data project separately (without UI project dependency).

If possible please give an working code for this scenario.

Thanks in Advance


Solution

  • I found a solution to use AbstractFactory pattern to use in conjunction with simple-injector container class for this problem .

    I still not sure whether this is a appropriate solution for this problem

    1. DataRepositoryFactory implementations,

      //Abstract data repository factory
      public interface IDataRepositoryFactory
      {
          T GetDataRepository<T>() where T : IDataRepository;
      }
      public class DataRepositoryFactory : IDataRepositoryFactory
      {
          T IDataRepositoryFactory.GetDataRepository<T>()
          {
              return (T)DataBootStraper
                       .DataDIContainer
                       .GetInstance(typeof(T));
          }
      }  
      
    2. in MyApp.Data project I created static Bootstrap class which use to register the data layer dependencies.

      public static class DataBootStraper
      {
          public static void BootStrap(Container container)
          {
              container.Register<IRepositoryA, RepositoryA>();
              container.Register<IRepositoryB, RepositoryB>();
              container.Register<IRepositoryC, RepositoryC>();
              //Register the DataRepositoryFactory also with container
              container.Register<IDataRepositoryFactory, DataRepositoryFactory>();
          }
      }
      

    So this can be called from my Unit test cases as well as UI bootstraper.

    1. Below is the example of the usage of factory

      public class DataRepositoryFactoryTest
      {
          private readonly IDataRepositoryFactory _repositoryFactory;
          public DataRepositoryFactoryTest(IDataRepositoryFactory repositoryFactory)
          {
              _repositoryFactory = repositoryFactory;
          }
          public IEnumerable<RepoAEntities> GetEntitiesFromRepoA()
          {
              return _repositoryFactory.GetDataRepository<IRepositoryA>().GetEntities();
          }
          public IEnumerable<RepoBEntities> GetEntitiesFromRepoB()
          {
              return _repositoryFactory.GetDataRepository<IRepositoryB>().GetEntities();
          }
          public IEnumerable<RepoCEntities> GetEntitiesFromRepoC()
          {
              return _repositoryFactory.GetDataRepository<IRepositoryC>().GetEntities();
          }
      }