当前位置: 首页 > 知识库问答 >
问题:

在核心依赖注入中注册类型时如何处理混合asp.net构造函数参数

夹谷承安
2023-03-14

我想知道如何在ASP中处理依赖注入。NET核心,用于同时具有对象和字符串作为参数的类型。由于字符串无法注册到DI框架,我目前正在使用implementationfactory并使用服务定位器模式,还有其他方法吗?是否有类似于Autofac的命名参数的.WithParameter?

Asp.net核心DI使得向DI框架注册一个类型变得容易(并且干净),对于那些已经向DI框架注册了参数的类型。

给定以下三个构造函数:

  public MyStateService() { /* .... */ }
  public MyServiceBackend(IMyStateService state) { /* .... */}
  public MyServiceClient(IMyStateService state, IMyServiceBackend backend, string logConfigPath) { /*.... */ }

前两种类型很容易注册到 DI 容器,如下所示:

  services.AddScoped<IMyStateService , MyStateService>();
  services.AddScoped<IMyServiceBackend, MyServiceBackend>();

然而,对于第三个,我必须使用实现工厂并使用服务定位器模式来获取要注入的前两种类型。

  services.AddScoped<IMyServiceClient, MyServiceClient>((ctx) =>
  {
      IMyStateService state= ctx.GetRequiredService<IMyStateService >();
      IMyServiceBackend backend = ctx.GetRequiredService<IMyServiceBackend>();
      return new MyServiceClient(state, backend, _serilogConfigPath);
  }); 
            
            

我的技术项目热衷于看到服务定位器[反模式],并要求一个没有服务定位器的解决方案。如果我们使用Autofac,我们可以使用.WithParameter()来命名参数,但dotnet core di没有,对吗?还有其他优雅的方式吗?

共有1个答案

须巴英
2023-03-14

利用ActivatorU实用程序

public static T CreateInstance<T> (IServiceProvider provider, params object[] parameters);

哪个

使用直接和/或从IServiceProvider提供的构造函数参数实例化类型。

//...

services.AddScoped<IMyServiceClient, MyServiceClient>((provider) => {
    return ActivatorUtilities.CreateInstance<MyServiceClient>(provider, _serilogConfigPath);      
}); 

//...

在上面的示例中,提供程序将用于解析其他依赖项,而字符串参数将直接提供。

如果目标类可以重构,那么不要显式依赖于字符串。考虑使用选项模式

参考:ASP.NET 核心中的期权模式

创建一个具体类来存储所需的数据

public class LogConfigOPtions {
    public string Path { get; set; }
}

重构目标类以依赖它

//...
string string logConfigPath;

//ctor
public MyServiceClient(IMyStateService state, IMyServiceBackend backend, IOptions<LogConfigOPtions> options) { 

    logConfigPath = options.Value.Path;

    //...
 }

最后,在注册服务时相应地配置选项

//...

services.Configure<LogConfigOPtions>(option => {
    option.Path = _serilogConfigPath;
});
services.AddScoped<IMyServiceClient, MyServiceClient>();
services.AddScoped<IMyStateService , MyStateService>();
services.AddScoped<IMyServiceBackend, MyServiceBackend>();

//...
 类似资料:
  • 我正试图在计算机上实现这个例子https://developer.android.com/jetpack/docs/guide.这就解释了Android应用程序的结构。 当我使用相同的代码时,我会出现以下错误。 我可以找出这个错误与 当我为ViewModel编写默认的零输入构造函数时,我得到了以下错误。 我想不出这个错误的原因和解决方法。

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 我有一个Azure Functions应用程序,它使用在[WebJobsStartup]中初始化的自定义参数绑定-如何将这些绑定迁移到新的[FunctionsStartup]方式? 在[WebJobsStartup]中,通过调用生成器注册绑定。带有.AddBindingRule的AddExtension 现在,新的Azure SDK说要使用[FunctionsStartup]——我该如何连接(或替

  • 我有一个自定义类,它有一个参数化构造函数 因此,实例化时需要3个参数。如果我想将这个类作为依赖项添加,我发现在Spring中没有直接的方法可以做到这一点。 我知道我可以简单地创建一个类的新实例并使用它的方法。但是我找不到任何直接的方法将这个类注入我的另一个类,即Rest控制器。 需要注意的是:所有3个参数都需要在运行时传递。我不能从属性文件中使用它们 即使Spring中没有直接的方法,我也想知道定

  • 和另一个类: 在这种情况下,服务将按照预期注入到A类中。据我所知,你不能在a类中使用构造函数,否则注入将无法工作。有没有一种方法可以在a类中使用一个构造函数,同时注入服务?即: 在这种情况下,我得到的服务是空的,无论如何要解决这个问题?我希望能够从类型A中使用“new”创建一个对象,并注入服务,这可能吗?

  • 我的大多数服务通常与crud方法相同