自动法克运行时参数

本文关键字:运行时 参数 | 更新日期: 2023-09-27 18:17:44

我是 autofac 的新手,希望了解将运行时值传递给构造函数的最佳实践。 我读过一堆堆栈溢出问题,其中提出了这个问题,但没有一个是完全充实的。 我们应该使用委托,工厂来创建服务等吗? 我知道传递容器不是实现这一目标的最佳方式。

在我的特殊情况下,我有一个访问多个依赖项的服务,例如日志记录、数据提供程序等。 除了传递的少数服务外,我还需要捕获运行时参数,例如用户ID,密码。 用户标识和密码是某些服务所必需的,当 Web 查看器执行特定操作时会查找。以下是我所拥有的,并强调了问题。

public class SomeService : ISomeService
{
    private readonly IDataProvider _dataProvider;
    private readonly ILog _log;
    private readonly string _username;  
    private readonly string _password;
    public SomeService(IDataProvider dataProvider, ILog log,
        string username, string password)
    {
      _dataProvider = dataProvider;
      _log = log;
      _username = username;
      _password = password;
    }
}

数据提供程序和日志在 autofac 中配置

builder.RegisterType<DataProviderService>().As<IDataProvider>()
builder.RegisterType<SomeLogService>().As<ILog>()

这个"SomeService"的大多数功能都需要用户名和密码在执行任务之前进行验证,因此最好在创建时传递到构造函数中,但从未处理过 autofac 的运行时要求。 我已经回顾了问题 Autofac - 无需传递容器即可解析运行时参数,它似乎接近我的需求,但需要更多关于实现这一目标的最佳方法的反馈。

自动法克运行时参数

AutoFac 支持通过参数化实例化的概念解析具有运行时参数的服务。

在依赖于具有特定运行时参数服务的客户端的构造函数中,将依赖项声明为Func,该根据其强类型参数返回该依赖项。

例如 Func<string, ISomeService> myService

当 AutoFac 看到Func时,它会创建一个委托,该委托充当创建服务的工厂方法。

从文档中:

如果类型T已注册到容器,则Autofac将自动 将 Func 上的依赖关系解析为创建 T 实例的工厂 通过容器。

依赖项

的参数列表中不可能有重复的类型,就像问题中的ISomeService一样。 例如 Func<string, string, ISomeService>行不通。在这种情况下,您需要提供自定义委托工厂。

从文档中:

工厂适配器提供容器的实例化功能 到托管组件,而不向它们公开容器本身。

实现此方法的一种方法是声明委托类型以及 AutoFac 将用作工厂方法的类型定义。

例如

public class SomeService : ISomeService
{
    // Factory method
    public delegate SomeService Factory(string userName, string password);
    public SomeService(IDataProvider dataProvider,
        ILog log,
        string username,
        string password)
    {
        // ..

然后,您的 ISomeService 客户端将如下所示:

public class MyClient
{
    public MyClient(SomeService.Factory serviceFactory)
    {
        // Resolve ISomeService using factory method
        // passing runtime parameters
        _myService = serviceFactory("this", "that");
    }
}

请注意,服务的所有非运行时参数(在您的情况下为 IDataProvider 和 ILog(将继续由容器自动解析。

通常,应防止将运行时值传递到构造函数中。这将使您的设计和 DI 配置变得非常复杂。构造函数用于依赖项和配置值。通过方法参数传递运行时值,或注入允许您检索这些运行时值的服务。以允许检索当前登录用户名称的IUserContext服务为例。