如何将运行时参数作为泛型类的依赖项解析的一部分传递?

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

这里回答了类似的问题:

How can I pass a runtime parameter as part of the dependency resolution?

但是,我想知道在注册泛型类时如何做到这一点?

通常,我会将其注册如下:

services.AddScoped(typeof(ITest<>), typeof(Test<>));

但是如果我想将运行时参数传递给构造函数呢?不使用DI,它将是这样的:

new Test<MyClass>(string mystring, int myInt)

在链接的答案中,建议使用工厂方法,但如果我没有传递确切的类型,这会给我一个错误。

另一种方法是获取一个实例而不在构造函数中传递运行时参数,而是在获取精确实例后使用setter方法。我想避免这种情况,因为每次获得实例后你都必须记得调用setter方法。

它有什么办法吗?我想我可以使用一些工厂类而不是在启动类中注册它...

编辑:在阅读史蒂文的答案非常有用之后,我用更具体的例子更新了问题:以下示例是在某个方法中:

//instance of repository are passed inside constructor of class
//calling some to update/insert
//IMPORTANT - calling external service I want save parameters to db no matter what
using(var ctx=new DbContext())
{
//create log object
ctx.logs.add(Obj)
ctx.save()
}
//some code after

假设我想要保持一致并调用我的loggingrepository的方法,并添加日志对象并将所有内容保存到数据库但是,构造函数中的每个存储库都接受DbContext,它注册为作用域(durig one request)。如果它在内部事务中,保存取决于调用外部服务后的代码,它可以抛出异常并保存任何内容。

所以,是的,我可以创建新的dbContext并将其传递给日志记录方法或调用一些私有日志记录功能并保存在其中,但重点是,如果我要求loggingRepository的实例,我希望DI将这个localy创建的dbContext变量传递给构造函数并且没有一个在启动方法中注册为作用域,因此无论外部服务或代码在调用之后发生了addind和save日志。

我的情况类似,但它是基于当前用户的db中的一些数据,我不想将相同的参数传递给众多方法,但只在类构造函数中。

asp.net-core dependency-injection asp.net-core-2.0 ioc-container
1个回答
2
投票

将原始配置值注入应用程序组件的一般解决方案是将它们提取到Parameter Object中。这为这些值提供了一个新的,明确的类型,可以注册到您的容器中:

// Parameter Object
public TestConfiguration
{
    public string Mystring;
    public int MyInt;
}

// (Generic) class using the Parameter Object
public class Test<T>
{
    public Test(TestConfiguration config) { ... }
}

// Registering both
services.AddScoped(typeof(ITest<>), typeof(Test<>));
services.AddSingleton(new TestConfiguration { Mystring = ..., Myint = ... });

配置值不被视为运行时数据,因为它们的值在启动时是已知的,并且在应用程序的持续时间内是常量。这就是为什么您可以将它们提供给应用程序组件的构造函数。

但是,实际运行时数据不应在构造期间传递给组件。运行时数据是在启动时未知的值,通常由用户通过Web请求传递,从数据库,会话或在应用程序生命周期内可能更改的任何内容中检索。

不应该通过构造函数传递运行时数据,而应该:

  1. 通过API或的方法调用传递运行时数据
  2. 从允许解析运行时数据的特定抽象中检索运行时数据。

您可以找到有关传递运行时数据here的更多信息。

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