如何在 C# 中为带有构造函数参数的类合并依赖注入?

问题描述 投票:0回答:1

给出以下代码:

public interface ISomeClient;

public class SomeClient : ISomeClient
{
  SomeClient(string clientID, string clientSecret) {
    _clientID = clientID;
    _clientSecret = clientSecret;
  }
}

public class SomeWrapper {
  SomeWrapper(ISomeClient someClient) {
    _someClient = someClient;
  }
}

此代码应该允许依赖项注入,但我不喜欢依赖项“某些客户端”需要参数。这似乎不是一个干净的方法。在让用户轻松使用“SomeWrapper”的同时进行这种类型的分离的正确方法是什么?

我考虑过的解决方案是:

  • 实例化 'SomeWrapper' 类时传入参数
  • 创建一个工厂类并使用工厂类通过构造函数参数实例化对象
  • 使用单独的方法在构造函数之外传入参数
  • 合并班级
c# dependency-injection
1个回答
0
投票

所提供的代码的主要问题是 SomeClient 类需要构造函数参数,这可能会使其在 SomeWrapper 类中使用起来不太方便。这可能会导致潜在的耦合和应用程序设计灵活性的降低。

有效的依赖注入解决方案:

要解决此问题并实现干净的依赖项注入,请考虑以下方法:

  1. 带有可选参数的构造函数注入:

重构 SomeClient:修改 SomeClient 类以在其构造函数中接受可选参数。这允许您提供默认值或使用依赖项注入来提供参数。

public class SomeClient : ISomeClient
{
    public SomeClient(string clientID = null, string clientSecret = null)
    {
        _clientID = clientID ?? "defaultClientID";
        _clientSecret = clientSecret ?? "defaultClientSecret";
    }
}

优点: 保持清晰的关注点分离。 提供如何提供参数的灵活性。 可以与其他依赖注入技术结合使用。

注意事项: 确保默认值适合您的用例。 考虑使用依赖注入框架来自动管理参数注入。

  1. 依赖注入框架:

利用框架:使用依赖注入框架,如 Microsoft 内置的 IServiceProvider 或第三方库,如 Autofac 或 SimpleInjector。 配置服务:向依赖项注入容器注册 SomeClient 和 SomeWrapper,并提供必要的参数。 使用 Microsoft 的 IServiceProvider 的示例:

public class SomeWrapper
{
    public SomeWrapper(ISomeClient someClient)
    {
        _someClient = someClient;
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<ISomeClient, SomeClient>();
        services.AddTransient<SomeWrapper>();
    }
}

优点: 简化依赖关系管理并减少样板代码。 提供生命周期管理和依赖关系解析等功能。 与 .NET 生态系统的其他部分很好地集成。

注意事项: 需要额外的设置和配置。 可能会为新团队成员引入学习曲线。

  1. 工厂模式:

创建工厂类:实现一个工厂类,负责创建具有所需参数的 SomeClient 实例。

public class SomeClientFactory
{
    public ISomeClient CreateClient(string clientID, string clientSecret)
    {
        return new SomeClient(clientID, clientSecret);
    }
}

优点: 提供用于创建实例的集中点。 可以封装复杂的实例化逻辑。 提供选择创建方法的灵活性。

注意事项: 如果广泛使用,可能会带来额外的复杂性。 需要仔细管理工厂实例。

  1. 单独方法:

提取参数传递:创建一个单独的方法来处理向 SomeClient 传递参数。

public class SomeWrapper
{
    public SomeWrapper(string clientID, string clientSecret)
    {
        _someClient = CreateSomeClient(clientID, clientSecret);
    }

    private ISomeClient CreateSomeClient(string clientID, string clientSecret)
    {
        return new SomeClient(clientID, clientSecret);
    }
}

优点: 可以提高代码的组织性和可读性。 为参数传递提供一定程度的抽象。

注意事项: 如果广泛使用,可能会带来额外的复杂性。 可能不如其他方法那么灵活。

选择正确的方法:

最佳方法取决于您的具体项目要求和偏好。考虑以下因素:

参数传递的复杂性:如果参数传递相对简单,带有可选参数的构造函数注入可能就足够了。 与其他框架集成:如果您使用依赖项注入框架,那么利用其功能可能会有所帮助。 代码组织和可维护性:评估每种方法如何影响代码的整体结构和可读性。 通过仔细考虑这些因素并应用适当的技术,您可以有效地将依赖项注入合并到 C# 代码中,从而促进更好的模块化、可测试性和可维护性。

© www.soinside.com 2019 - 2024. All rights reserved.