Question

I'm having trouble trying to figure out how to solve a dependency issue within my architecture. I'm using NHibernate and I'm trying to abstract its ICriteria interface with my own ICriteriaItem interface. ICriteriaItem is used in my Repository Interfaces:

ICriteriaItem.cs

public interface ICriteriaItem
{
    string PropertyName { get; set; }
    object Value { get; set; }
}

IUserRepsository.cs

public interface IUserRepository 
{
    IEnumerable<User> Find(IList<ICriteriaItem> criteria);
}

My service layer uses this repository in its AccountService

AccountService.cs

public class AccountService : IAccountService
{
    private IUserRepository _userRepo;
    private IRoleRepository _roleRepo;

    public AccountService(IUserRepository userRepository,
        IRoleRepository roleRepository)
    {
        _userRepo = userRepository;
        _roleRepo = roleRepository;
    }

    public ValidateUser(string username, string password)
    {
        password = HashPassword(password);

        _userRepo.Find(new List<ICriteriaItem>() {
            new CriteriaItem() { "Username", username },
            new CriteriaItem() { "Password", password},
        });
    }
}

My problem is with getting an instance of CriteriaItem with Ninject. All of my binding has been done in my MVC layer and currently, my service layer knows nothing about Ninject. My services are already injected in the constructor. So here are my options:

  1. I could just inject ICriteriaItem into the constructor. This feels dirty as every service will have this injected. I'm sure I could do this with a base repository, but it still feels dirty.

  2. Inject my kernel and use that in my service to get an instance of ICriteriaItem. Feels even worse.

  3. Just expose the concrete class for ICriteriaItem and do away with the interface.

  4. Find another way...

Thoughts? Am I going at this all wrong? Is there a better way? What am I missing here?

Was it helpful?

Solution

You could use a factory pattern, and inject that into your AccountService constructor.

public ICriteriaItemFactory
{
    ICriteriaItem GetNew();
}

Now, your implementation of this will need to accept an IKernel dependency, but at least you're not injecting the kernel into one of your core classes.

public CriteriaItemFactory : ICriteriaItemFactory
{
    private IKernel _kernel;

    public CriteriaItemFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public ICriteriaItem GetNew()
    {
        return _kernel.Get<ICriteriaItem>();
    }
}

OTHER TIPS

CriteriaItem is a data transfer object. DTOs should never have any dependencies and therefore they shouldn't be created using Nnject. The current implementation is like it should be.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top