Autofac运行时参数

我是autofac的新手,希望看到将运行时值传递给构造函数的最佳实践。 我已经阅读了一堆stackoverflow问题,但是没有一个完全充实。 我们应该使用代表,工厂来创建服务等。我知道传递容器并不是实现这一目标的最佳方法。

在我的特定情况下,我有一个访问多个依赖项的服务,比如日志记录,数据提供者等。除了传递的少量服务之外,我还需要捕获运行时参数,比如userid,password。 SomeService需要用户标识和密码,并在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().As() builder.RegisterType().As() 

这个“SomeService”的大多数function都需要用户名和密码才能在执行任务之前进行validation,因此最好在创建时传递给构造函数,但从未处理过autofac的运行时要求。 我已经回顾了Autofac这个问题- 解决运行时参数而不必传递容器 ,它似乎接近我需要但需要更多关于实现此目的的最佳方法的反馈。

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

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

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

例如Func myService

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

从文档:

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

在您的依赖项的参数列表中不可能有重复的类型,就像问题中的ISomeService 。 例如Func将不起作用。 在这种情况下,您需要提供自定义委托工厂 。

从文档:

工厂适配器为托管组件提供容器的实例化function,而不会将容器本身暴露给它们。

实现此方法的一种方法是声明委托类型以及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)。