【问题标题】:C# Dependency Injection - good practicesC# 依赖注入 - 良好实践
【发布时间】:2018-12-28 17:04:15
【问题描述】:

我在理解如何创建可注入类方面遇到了一些问题……

这是我的例子:

public interface IService
{
  string FindSomeData()
}

现在我们创建一个实现接口的类:

public class FolderService : IService
{
  private string _path;

  public FolderService(string path)
  {
    _path = path;
  }

  public string FindSomeData()
  {
    //Open a folder using _path and find some data
  }
}

也许还有其他类:

public class DbService : IService
    {
      private MyConnectionClass _connection;

      public DbService(MyConnectionClass connection)
      {
        _connection = connection;
      }

      public string FindSomeData()
      {
        //Connect to database using _connection object and find some data
      }
    }

现在我想将其中一个类添加到 IoC Container e.x.:

if (InDebug)
 SimpleIoc.Default.Register<IService, FolderService>();
else
 SimpleIoc.Default.Register<IService, DbService>();

并且知道我有问题。 当我想将此对象传递给其他一些类的构造函数时:

public MyViewModel(IService service)
{
 _service = service;
}
// Read folder name from TextBox on View and then call _service.FindSomeData

然后我想在这种情况下将用户选择的路径传递给 IService 对象 (FolderService)。 我应该如何以正确的方式做到这一点(根据 SOLID 和其他良好的实践模式......)?

一旦我应该传递字符串(文件夹路径),一次是 MyConnectionClass(如果连接到数据库)。 做这种事情的最佳方法是什么?

最好的问候, 迈克尔

【问题讨论】:

  • 谢谢@YannickMeeus,但这不是我要求的——我知道如何使用参数化构造函数注册类。问题是不同的。我问编写这样的类并将它们传递给 IoC 容器是否是一种好习惯。 IService 不应该知道它将从哪个数据存储中下载数据 - 我已将此功能移至派生类。问题是当用户更改(例如文件夹路径)时,我应该使用更改的构造函数参数再次实例化 IService 对象...
  • 那就跑题了 ;) .. 包含该路径的配置文件怎么样?
  • @nilsK 路径或连接字符串可以在应用程序工作期间更改:/
  • @Roofy 所以你有不同的数据库上下文?您可以编写通用/基本上下文并从中派生。 AContext:基本上下文。这样,您当然需要为每个上下文创建一个连接字符串,并将其加载到派生的上下文构造函数中。

标签: c# dependencies inversion-of-control code-injection


【解决方案1】:

您可以将文件夹路径提供/更改逻辑封装到单独的提供程序中,例如 IFolderPathProvider 并将其注入 FolderService

public interface IFolderPathProvider {
    string GetFolderPath();
    void SetFolderPath(string);
}

public class FolderPathProvider : IFolderPathProvider  {
    ...
}

public class FolderService : IService
{
  private IFolderPathProvider _folderPathProvider;

  public FolderService(IFolderPathProvider folderPathProvider)
  {
    _folderPathProvider = folderPathProvider;
  }

  public string FindSomeData()
  {
    string path = _folderPathProvider.GetFolderPath();
    //Open a folder using path and find some data
  }
}

当用户更改路径时,将IFolderPathProvider 注入处理程序并调用SetFolderPath。同样,您可以创建IDbConnectionProvider。根据具体情况,它们可以合并为一个DataConfigProvider,但我不确定你到底需要什么;主要思想是将文件夹路径/数据库连接更改逻辑从服务中分离出来,并继续使用依赖注入。

【讨论】:

  • 巴格丹·吉列维奇非常感谢您。这是一个非常好的主意。这正是我所需要的——我想将 IService 的逻辑与数据的查找方式分开,并使 DI 成为可能。我认为您的想法是非常好的解决方案。谢谢你们所有的答案。最好的问候,米哈乌
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-08
  • 2010-12-11
  • 1970-01-01
  • 2019-05-23
  • 1970-01-01
相关资源
最近更新 更多