You should enter only one repository for each object in the consumer, which depends on it. You can also adapt the repository to a business class broker.
UPDATE
Based on the information presented in the question and problem statement, here is one of the possible solutions. Define your core infrastructure as follows:
public abstract class Entity<TEntity, TDomainObject, TIRepository> where TEntity : Entity<TEntity, TDomainObject, TIRepository> where TDomainObject : Entity<TEntity, TDomainObject, TIRepository>.BaseDomainObject, new() where TIRepository : Entity<TEntity, TDomainObject, TIRepository>.IBaseRepository { public class BaseDomainObject {} public interface IBaseRepository { IEnumerable<TDomainObject> GetAll(); IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper); } public class BaseRepository : IBaseRepository { public IEnumerable<TDomainObject> GetAll() { return new List<TDomainObject>(); } public IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper) { return this.GetAll().Select(mapper); } } }
Define your source objects as follows:
public class SourceA : Entity<SourceA, SourceA.DomainObject, SourceA.IRepository> { public class DomainObject : BaseDomainObject { public string Name; public int Age; } public interface IRepository : IBaseRepository {} public class Repository : BaseRepository, IRepository {} } public class SourceB : Entity<SourceB, SourceB.DomainObject, SourceB.IRepository> { public class DomainObject : BaseDomainObject { public string Name; public decimal Weight; } public interface IRepository : IBaseRepository {} public class Repository : BaseRepository, IRepository {} } public class SourceC : Entity<SourceC, SourceC.DomainObject, SourceC.IRepository> { public class DomainObject : BaseDomainObject { public Guid Id; public string Name; } public interface IRepository : IBaseRepository {} public class Repository : BaseRepository, IRepository {} }
Then define an ISourceRepositoryContext interface similar to this, and add here each source repository interface:
public interface ISourceRepositoryContext { SourceA.IRepository SourceARepository { get; } SourceB.IRepository SourceBRepository { get; } SourceC.IRepository SourceCRepository { get; } }
Then define the default implementation for the interface:
public class DefaultSourceRepositoryContext : ISourceRepositoryContext { public SourceA.IRepository SourceARepository => new SourceA.Repository(); public SourceB.IRepository SourceBRepository => new SourceB.Repository(); public SourceC.IRepository SourceCRepository => new SourceC.Repository(); }
Define result transport objects:
public class Dog { public string Name; public int Age; } public class Cat { public string Name; public decimal Weight; } public class Fish { public Guid Id; public string Name; } public class MyObject { public IEnumerable<Cat> Cats { get; set; } public IEnumerable<Dog> Dogs { get; set; } public IEnumerable<Fish> Fish { get; set; } }
Then use the ISourceRepositoryContext class in your BusinessLogic class:
public class BusinessLogic { protected ISourceRepositoryContext repositories; public BusinessLogic(ISourceRepositoryContext repositories) { this.repositories = repositories; } public MyObject GetResults(string param1) { return new MyObject() { Dogs = this.repositories.SourceARepository.GetAllMapped (domainObject=>new Dog { Age = domainObject.Age, Name = domainObject.Name }), Cats = this.repositories.SourceBRepository.GetAllMapped (domainObject=>new Cat { Name = domainObject.Name, Weight = domainObject.Weight }), Fish = this.repositories.SourceCRepository.GetAllMapped (domainObject=>new Fish { Id = domainObject.Id, Name = domainObject.Name }), }; } }
I confirmed that the above compiles under C # 6.0.
I would recommend changing the IRepository for IBusiness to Entity and sharing the data access problems with the IDataAccess interface that only IBusiness developers get through their designers. Then change the ISourceRepositoryContext to ISourceEntities and change the IRepository properties in this interface to IBusiness properties.
The BusinessLogic class is the part that really bothers me. Are you sure that in this class there will not be too many problems? Is it supposed to be a UoW class?
For a more complete solution based on similar methods, check out my answer to this other question: .NET Layer Relationship Management