自动法克运行时参数
本文关键字:运行时 参数 | 更新日期: 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
服务为例。