.net - 组件架构和 DI 容器的使用?

标签 .net oop architecture dependency-injection unity-container

我有一个 FTP 实用程序,负责通常的 FTP 操作:放置文件、获取文件等。作为我们基础设施的一部分,我们需要组件从实现 IConfiguration 接口(interface)的组件中检索其配置,并将其条目记录到实现 ILogger 接口(interface)的组件。请注意,ftp 主机是通过逻辑主机名(例如 someFtpSite)来描述的,该名称与配置文件中包含主机名、用户 ID 和密码的部分相匹配。所以我的接口(interface)和类定义是这样创建的:

public interface IFtpUtility
{
    void PutFile(string sourceFileAndPath, string targetFileAndPath, string logicalHost);
}

public class FtpUtility : IFtpUtility
{
    private readonly IConfiguration _configuration;
    private readonly ILogger _logger;

    public FtpUtility(ILogger logger, IConfiguration configuration)
    {
        _configuration = configuration;
        _logger = logger;
    }
    // IFtpUtility implementation follows
}

我使用此签名的目的是仅在需要操作(例如 PutFile)时才需要逻辑主机名,因此在 PutFile 方法本身上提供它。

这种布局非常适合与 Unity 等 IoC 容器一起使用。我们将有以下代码:

UnityContainer = new UnityContainer();
UnityContainer.RegisterType<IConfiguration, ConfigurationProvider>();
UnityContainer.RegisterType<ILogger, LoggingProvider>();
UnityContainer.RegisterType<IFtpUtility, FtpUtility>();

当稍后我需要使用 FtpUtility 时,我将依赖容器来进行适当的解析:

IFtpUtility ftpUtility = UnityContainer.Resolve<FtpUtility>();

现在,一位同事向我建议,逻辑主机名应该是构造函数上的一个参数,因为没有它,任何函数都无法执行,并且它或多或少与 FtpUtility 的特定实例相关联。每次调用我们只与一台 FTP 服务器通信。因此,我很高兴更改构造函数以包含逻辑主机名,这破坏了我的 IoC 容器解析。 请注意,虽然 IConfiguration 和 ILogger 可以与特定实现相关联,但逻辑主机特定于实例,直到创建实例时我们才知道。现在我可以说这样的改变会改变我的 IoC 容器的使用,因此我无法实现它,等等,但这个论点太弱了(我发现)。那么问题如下:

  • 从架构的角度来看,将逻辑主机放在构造函数上是好事还是坏事?
  • 逻辑主机名称是否是必需的构造参数,没有该参数 FtpUtility 就无法运行,因此应该成为构造函数的一部分?
  • 有没有办法用 Unity 解决这个问题?如果构造函数包含逻辑主机的第三个参数,是否有 Resolve<>() 的重载,允许我在解析时提供第三个参数的值,而不是提前将其注册到容器中?
  • 我是否正在尝试解决一个根本不存在的问题?在这种情况下使用 IoC 容器是否太过分了,不仅没有帮助,反而使事情变得复杂?毕竟,我仍在使用 IoC 模式 - 只是无法使用 IoC 容器自动或干净地解决它?

最佳答案

1,2。从抽象的角度来看,在构造函数中包含主机名是合乎逻辑的,也是一个理想的位置。

3,4。以我个人的观点,通过统一解析主机名有点矫枉过正,但完全可能。一个更简单的选择是实例化这是您的统一配置并从标准 app/web.config 中提取主机名,类似于下面(MVC 实现);

 container.RegisterType<IFtpUtility, FtpUtility>(
      new InjectionConstructor(ConfigurationManager.AppSettings["Hostname"]));

这很好地解耦了事物,并且仍然允许您根据需要配置该设置。

关于.net - 组件架构和 DI 容器的使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13843354/

相关文章:

c# - 我正在尝试为 Unity 映射通用类型

c# - System.Random 构造函数中的错误?

c# - 如何使用 .NET 和 Dapper.NET 执行此 sql 语句?

c++ - 在 C++ 中,我可以在定义自己的复制构造函数后跳过定义赋值运算符吗?

architecture - 如何控制敏捷项目中的架构?

architecture - MNesia 是否支持断线操作后的同步?

C#:代码契约与普通参数验证

javascript - JavaScript 中的 Java 式 OOP 和 jQuery 失败

asp.net - 为什么事件冒泡,为什么不直接订阅点击事件?

node.js - 更大的项目 Node.js 和 RESTful API