gpt4 book ai didi

c# - 如何将运行时参数作为依赖项解析的一部分传递?

转载 作者:IT王子 更新时间:2023-10-29 04:20:25 26 4
gpt4 key购买 nike

我需要能够将连接字符串传递到我的某些服务实现中。我在构造函数中这样做。连接字符串可由用户配置,将作为声明添加 ClaimsPrincipal。

到目前为止一切正常。

不幸的是,我也希望能够充分利用ASP.NET Core中的依赖注入(inject)特性,通过DI解决服务实现。

我有一个 POC 实现:

public interface IRootService
{
INestedService NestedService { get; set; }

void DoSomething();
}

public class RootService : IRootService
{
public INestedService NestedService { get; set; }

public RootService(INestedService nestedService)
{
NestedService = nestedService;
}

public void DoSomething()
{
// implement
}
}


public interface INestedService
{
string ConnectionString { get; set; }

void DoSomethingElse();
}

public class NestedService : INestedService
{
public string ConnectionString { get; set; }

public NestedService(string connectionString)
{
ConnectionString = connectionString;
}

public void DoSomethingElse()
{
// implement
}
}

这些服务已在启动期间注册,并且 INestedService 已添加到 Controller 的构造函数中。

public HomeController(INestedService nestedService)
{
NestedService = nestedService;
}

正如预期的那样,我在尝试激活“Test.Dependency.Services.NestedService”时收到错误Unable to resolve service for type 'System.String'。

我有哪些选择?

最佳答案

要传递在应用程序启动时未知的运行时参数,您必须使用工厂模式。您在这里有两个选择:

  1. 工厂类(类似于IHttpClientFactory的实现方式)

     public class RootService : IRootService
    {
    public RootService(INestedService nested, IOtherService other)
    {
    // ...
    }
    }

    public class RootServiceFactory : IRootServiceFactory
    {
    // in case you need other dependencies, that can be resolved by DI
    private readonly IServiceProvider services;

    public RootServiceFactory(IServiceProvider services)
    {
    this.services = services;
    }

    public IRootService CreateInstance(string connectionString)
    {
    // instantiate service that needs runtime parameter
    var nestedService = new NestedService(connectionString);

    // note that in this example, RootService also has a dependency on
    // IOtherService - ActivatorUtilities.CreateInstance will automagically
    // resolve that dependency, and any others not explicitly provided, from
    // the specified IServiceProvider
    return ActivatorUtilities.CreateInstance<RootService>(services,
    new object[] { nestedService, });
    }
    }

    并注入(inject) IRootServiceFactory 而不是你的 IRootService

     IRootService rootService = rootServiceFactory.CreateInstance(connectionString);
  2. 工厂方法

     services.AddTransient<Func<string,INestedService>>((provider) => 
    {
    return new Func<string,INestedService>(
    (connectionString) => new NestedService(connectionString)
    );
    });

    并将工厂方法注入(inject)您的服务而不是 INestedService

     public class RootService : IRootService
    {
    public INestedService NestedService { get; set; }

    public RootService(Func<string,INestedService> nestedServiceFactory)
    {
    NestedService = nestedServiceFactory("ConnectionStringHere");
    }

    public void DoSomething()
    {
    // implement
    }
    }

    或每次调用解决

     public class RootService : IRootService
    {
    public Func<string,INestedService> NestedServiceFactory { get; set; }

    public RootService(Func<string,INestedService> nestedServiceFactory)
    {
    NestedServiceFactory = nestedServiceFactory;
    }

    public void DoSomething(string connectionString)
    {
    var nestedService = nestedServiceFactory(connectionString);

    // implement
    }
    }

关于c# - 如何将运行时参数作为依赖项解析的一部分传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37744637/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com