关于C#:解决我的服务层中的依赖项

Resolving a dependency in my Service layer

我在尝试弄清楚如何解决体系结构中的依赖项问题时遇到了麻烦。我正在使用NHibernate,并且尝试使用自己的ICriteriaItem接口抽象其ICriteria接口。我的存储库接口中使用了ICriteriaItem:

ICriteriaItem.cs

1
2
3
4
5
public interface ICriteriaItem
{
    string PropertyName { get; set; }
    object Value { get; set; }
}

IUserRepsository.cs

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

我的服务层在其AccountService中使用此存储库

AccountService.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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一无所知。我的服务已经注入到构造函数中。所以这是我的选择:

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

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

  • 只需公开ICriteriaItem的具体类并取消该接口即可。

  • 寻找另一种方式...

  • 有什么想法吗?我要错了吗?有没有更好的办法?我在这里想念什么?


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


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

    1
    2
    3
    4
    public ICriteriaItemFactory
    {
        ICriteriaItem GetNew();
    }

    现在,您的实现将需要接受IKernel依赖关系,但是至少您没有将内核注入到您的核心类之一中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public CriteriaItemFactory : ICriteriaItemFactory
    {
        private IKernel _kernel;

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

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