I'm trying to decouple the Bll from the Dal using some interfaces and a Factory patter. Data.Contracts containing the interfaces will be referenced on my Bll.
This is a small test code:
class Program
{
static void Main(string[] args)
{
IDataRepositoryFactory _DataRepositoryFactory;
IUserRepository userRepository = _DataRepositoryFactory.GetDataRepository<IUserRepository>();
}
}
public abstract class RepositoryBase<T> where T : class, new() { }
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository() { }
}
public class DataRepositoryFactory : IDataRepositoryFactory
{
public T GetDataRepository<T>() where T : IDataRepository, new()
{
return ObjectBase.Container.GetExportedValue<T>();
}
}
public class User
{
public int Id { get; set; }
}
public abstract class ObjectBase
{
public ObjectBase() { }
public static CompositionContainer Container { get; set; }
}
public interface IDataRepository { }
public interface IDataRepository<T> : IDataRepository where T : class, new() { }
public interface IUserRepository : IDataRepository { }
public interface IDataRepositoryFactory
{
T GetDataRepository<T>() where T : IDataRepository, new();
}
An finally I got my error:
'Data.Contracts.IUserRepository' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Data.Contracts.IDataRepositoryFactory.GetDataRepository()'
My question is: Which is the correct implementation to Decouple the code on the Business layer using the factory pattern? I can not use the concrete implementation UserRepository since it inherits from classes that I do not want in the BLL.
Any help would be appreciated.
From the code perspective you should just disable "new" constraint on factory interface:
From the design point of view repositories look a bit complicated:
For me IDataRepository (non-generic) and RepositoryBase seem redundant, but that depends of the exact case (probably you didn't provide enough details). I'd use
IDataRepository<T> -> IUserRepository:IDataRepository<User> -> UserRepository
inheritance chain.Also it's not clear what types belong to BLL.
For example, this breakdown looks all right to me:
User
IUserRepository:IDataRepository<User>
IDataRepositoryFactory
IDataRepositoryFactory:IDataRepositoryFactory
IDataRepository<T>
UserRepository
In general I'd suggest to simplify code structure and start with the simplest possible way, then adding new interfaces/classes when you really need them.