Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Autofac运行时参数_C#_Inversion Of Control_Ioc Container_Autofac - Fatal编程技术网

C# Autofac运行时参数

C# Autofac运行时参数,c#,inversion-of-control,ioc-container,autofac,C#,Inversion Of Control,Ioc Container,Autofac,我是autofac的新手,希望了解将运行时值传递给构造函数的最佳实践。我读过很多关于stackoverflow的问题,其中都有这样的问题,但没有一个是完全充实的。我们应该使用代理、工厂来创建服务等。我知道传递容器不是实现这一点的最佳方式 在我的特殊情况下,我有一个访问多个依赖项的服务,比如日志记录、数据提供者等。除了传递的少数服务之外,我还需要捕获运行时参数,比如userid、密码。SomeService需要用户ID和密码,并且在web查看器执行特定操作时会进行查找。下面是我所看到的,重点是这个

我是autofac的新手,希望了解将运行时值传递给构造函数的最佳实践。我读过很多关于stackoverflow的问题,其中都有这样的问题,但没有一个是完全充实的。我们应该使用代理、工厂来创建服务等。我知道传递容器不是实现这一点的最佳方式

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

此“SomeService”的大部分功能都需要用户名和密码才能在执行任务之前进行验证,因此在创建时最好将其传递给构造函数,但从未处理过autofac的运行时要求。我已经回顾了这个问题,它似乎接近于我所需要的,但需要更多的反馈,以找到实现这一目标的最佳方法。

一般来说,你应该这样做。这将使您的设计和DI配置复杂化很多。构造函数用于依赖项和配置值。通过方法参数传递运行时值,或者注入一个允许您检索这些运行时值的服务。以一个
IUserContext
服务为例,该服务允许检索当前登录用户的名称。

AutoFac通过以下概念支持使用运行时参数解析服务

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

例如
Func-myService

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

从文件中:

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

在依赖项的参数列表中不可能有重复的类型,就像您问题中的
isomservice
一样。例如,
Func
将不起作用。在这种情况下,您需要提供一个

从文件中:

工厂适配器提供容器的实例化功能 在不向托管组件公开容器本身的情况下,将其复制到托管组件

实现此方法的一种方法是在AutoFac将用作工厂方法的类型定义旁边声明委托类型

例如

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

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

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

您能否更具体地说明什么是
SomeService
,以及它如何使用用户名和密码信息?这使得任何人都可以给你一些更具体的建议。难道“配置值”不是典型的“运行时值”吗。这些是不变的;它们在应用程序的过程中不会改变。只是一个极客的观点,但我觉得这种方法不会带来好的类设计。在我看来,类实现甚至不应该意识到DI/IoC正在发生的事实。如果类在构造时需要一个值,我会将其作为参数;无论Autofac的观点/能力如何,我都会有这样的感觉,但碰巧是这样,正如前面提到的,Autofac确实通过参数化实例化来支持这一点。
public class MyClient
{
    public MyClient(SomeService.Factory serviceFactory)
    {
        // Resolve ISomeService using factory method
        // passing runtime parameters
        _myService = serviceFactory("this", "that");
    }
}