c# - 接口(interface)和依赖注入(inject)在 C# 中的正确使用

标签 c# interface dependency-injection loose-coupling

我有一个接口(interface)“IUser”和一个实现“IUser”的类“User”。我还有一个存储库“IUserRepository”的接口(interface)。

我介于这两个选项之间:

public interface IUserRepository
{
    List<User> getAll();
    void addUser(User user);
    void alterUser(User user);
    void deleteUser(string ID);
    bool validateLogin(string session_user, string session_pass);
    User getUserByID(int ID);
    User getUserByNombre(string name);
    User getUserBySessionUser(string session_user);
}

还有这个

public interface IUserRepository
{
    List<IUser> getAll();
    void addUser(IUser user);
    void alterUser(IUser user);
    void deleteUser(string ID);
    bool validateLogin(string session_user, string session_pass);
    IUser getUserByID(int ID);
    IUser getUserByNombre(string name);
    IUser getUserBySessionUser(string session_user);
}

这是我的困惑。我在存储库接口(interface)中的方法应该返回真正的实现或接口(interface)吗?正如您在我的第一个选项中看到的那样,我正在返回“用户”实例。我应该返回什么来松耦合代码?

但如果我在我的用户存储库的实际实现中选择第二个,我将只能访问我在 IUser 接口(interface)中声明的方法和属性。

例如,如果我从服务中调用 addUser 方法并将其传递给 User 类的实例:

   myRepositoryImplementation.addUser(UserInstance);

然后我的真实仓库会这样

  private readonly IUser user;
  public void addUser(IUser _user)
  {
    this.user=_user;
  }

不错的有效捕获!但之后我将只能访问最初在 IUser 接口(interface)中声明的方法和属性,而不能访问在我的 User 实例中声明的任何新方法或属性。

另外,如果我调用 getUserByID 方法,我将收到一个 IUser 实例。

所以要恢复这个

1).这些是有效的方法吗?
2).如果这些是有效的方法,我应该使用哪一种来保留或保持代码解耦?
3).如果我也选择第二个,如果它有效,那么我是否应该在界面中声明我稍后要使用的所有内容?我是说属性和方法?
3).有更好的主意吗?

最佳答案

1) 是的,两者都有效

3) 是的,属性和方法

2) 长一点的故事。简而言之,如果你有 POCO 类,并且你 100% 确定你永远不会针对不允许你使用 POCO 的框架进行编码(例如,它坚持从特定于框架的基类继承类),您可以选择第一个选项(类(class))。

但它并不总是有效。

例如,为 Linq2SQL 编码存储库和为 Entity Framework Code First 编写其他存储库,您不能使用完全相同的一组类。第二种(接口(interface))方法是唯一的选择。我们已经在多个企业应用程序中成功使用它,没有出现任何问题。

忠告——如果你使用接口(interface)方法,你肯定需要一个方法来创建一个空实例

public interface IUserRepository
{
    List<IUser> getAll();
    ...
    IUser CreateNew();
}

否则,存储库客户端没有其他方法来创建具体类型的实例 - 客户端不知道该类型。不过,有些人倾向于将创建方法移至单独的工厂类。

关于c# - 接口(interface)和依赖注入(inject)在 C# 中的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25691116/

相关文章:

arrays - 如何使用 typescript 的字符串索引接口(interface)?

dependency-injection - 如何注入(inject)数据类

dependency-injection - DI : Composition root decomposition

c# - 如何使用 Office Open XML SDK 2.0 获取列标题列表?

c# - 从资源文件夹 iOS Unity 中的文件夹创建按钮

interface - 在 Go 的接口(interface)中列出接口(interface)

c# - RabbitMQ:注入(inject)连接工厂

c# - 运行时 Ninject 绑定(bind)

c# - Azure Functions 自定义日志记录的最佳实践是什么?

java - 从核心接口(interface)调用自定义方法