解决我的服务层中的依赖项

时间:2012-08-03 19:24:24

标签: c# ninject repository-pattern n-tier-architecture onion-architecture

我无法弄清楚如何在我的架构中解决依赖问题。我正在使用NHibernate,我正在尝试使用自己的ICriteriaItem接口抽象其ICriteria接口。 ICriteriaItem用于我的存储库接口:

ICriteriaItem.cs

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

IUserRepsository.cs

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

我的服务层在其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},
        });
    }
}

我的问题是使用Ninject获取CriteriaItem的实例。我的所有绑定都在我的MVC层中完成,目前,我的服务层对Ninject一无所知。我的服务已经在构造函数中注入了。所以这是我的选择:

  1. 我可以将ICriteriaItem注入构造函数中。这感觉很脏,因为每个服务都会注入这个。我确信我可以使用基本存储库执行此操作,但它仍然感觉很脏。

  2. 注入我的内核并在我的服务中使用它来获取ICriteriaItem的实例。感觉更糟。

  3. 只需公开ICriteriaItem的具体类,然后取消界面。

  4. 找另一种方式......

  5. 思考?我错了吗?有没有更好的办法?我在这里缺少什么?

2 个答案:

答案 0 :(得分:4)

CriteriaItem是一个数据传输对象。 DTO应该永远不具有任何依赖关系,因此不应使用Nnject创建它们。当前的实现就像它应该的那样。

答案 1 :(得分:2)

您可以使用工厂模式,并将其注入 AccountService 构造函数。

public ICriteriaItemFactory
{
    ICriteriaItem GetNew();
}

现在,您的实现需要接受 IKernel 依赖关系,但至少您不会将内核注入其中一个核心类。

public CriteriaItemFactory : ICriteriaItemFactory
{
    private IKernel _kernel;

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

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