首页 > 解决方案 > 依赖注入,具有自定义和简单对象的构造函数

问题描述

我有一堂课如下-

public class GCCUPCCodeGenerator : IUPCCodeGenerator
{
    IPersistence _persistence;
    string _gccPrefix;

    public GCCUPCCodeGenerator(IPersistence persistence , string gccPrefix)
    {
        _persistence = persistence;
    }

如何在 Startup.cs 中完成此对象的依赖注入?

这是我所知道的-

A.如果这个类只需要 IPersistence 类,我会添加 -

   services.AddScoped<IPersistence, Persistence>();

B.最后,如果这是一个在构造函数中具有简单类型的类,我知道如何从 Config 中读取值来创建对象。

对于 UnixConnection 类 -

public class UnixConnection : IUnixDataStore
{
    public UnixConnection(UnixConnectionOption connectionOptions)
    {

启动.cs -

services.AddScoped<IUnixDataStore>(provider => ConfigureUnixConnectionObject());
IUnixDataStore ConfigureUnixConnectionObject()
    {
        var connectionParam = new UnixConnectionOption
        {
            DBPort = Convert.ToInt32(Configuration["DBPort"]),
            SSHUserName = Configuration["SSHUserName"],
            SSHHostName = Configuration["SSHHostName"],
            SSHPassword = Configuration["SSHPassword"],
            SQLHostName = Configuration["SQLHostName"],
            SQLUserName = Configuration["SQLUserName"],
            SQLPassword = Configuration["SQLPassword"],
            SQLDatabaseName = Configuration["SQLDatabaseName"]
        };
        return new UnixConnection(connectionParam);
    }

标签: c#asp.net-coredependency-injection

解决方案


您必须使用提供程序操作重载,这与您的第二种情况非常相似(具有讽刺意味的是,它不需要这个来完成它)。

services.AddScoped<IUPCCodeGenerator>(p =>
{
    // `p` is a scoped instance of `IServiceProvider`, meaning you can pull services from it
    var persistence = p.GetRequiredService<IPersistence>();
    return new GCCUPCCodeGenerator(persistence, "prefix");
});

前缀当然可以来自您的配置。

与您的问题无关,但由于我提到您不需要为您的IUnixDataStore. 如果您的配置使用了部分(它应该使用部分,因为在根目录中有一堆不相关的配置设置会导致混淆和错误),那么您可以UnixConnectionOptions通过强类型配置绑定部分。假设配置如下:

{
    "UnixConnection": {
      "DBPort": "...",
      "SSHUserName": "...",
      ...
    }
}

(注意:如果使用环境变量之类的东西,您可以使用:, 即“部分” UnixConnection:DBPort

然后:

services.Configure<UnixConnectionOption>(Configuration.GetSection("UnixConnection"));

在那之后,你有几个选择。如果您不介意注射IOptions<UnixConnectionOption>IOptionsSnapshot<UnixConnectionOption>取而代之,那么您就完成了。这实际上有好处,因为您可以利用配置重新加载等功能。

如果您真的想坚持UnixConnectionOptions直接注入,那么您只需添加另一行,例如:

services.AddScoped<UnixConnectionOptions>(p =>
    p.GetRequiredService<IOptions<UnixConnectionOptions>>().Value);

services.AddScoped<IUnixDataStore, UnixConnection>();

由于所需的依赖项直接在服务集合中,因此它可以直接注入,而无需您提供自定义操作。或者,您可以坚持目前的做法,但至少要利用精简的代码:

services.AddScoped<IUnixDataStore>(p => {
    var connectionParam = p.GetRequiredService<IOptions<UnixConnectionOption>>();
    return new UnixConnection(connectionParam.Value);
);

推荐阅读