Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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# 依赖项注入,使用参数注入_C#_Asp.net Core_Dependency Injection_Asp.net Core Mvc - Fatal编程技术网

C# 依赖项注入,使用参数注入

C# 依赖项注入,使用参数注入,c#,asp.net-core,dependency-injection,asp.net-core-mvc,C#,Asp.net Core,Dependency Injection,Asp.net Core Mvc,我正在使用DI的vNext实现。 如何将参数传递给构造函数? 例如,我有一门课: public class RedisCacheProvider : ICacheProvider { private readonly string _connectionString; public RedisCacheProvider(string connectionString) { _connectionString = connectionString;

我正在使用DI的vNext实现。 如何将参数传递给构造函数? 例如,我有一门课:

public class RedisCacheProvider : ICacheProvider
{
    private readonly string _connectionString;

    public RedisCacheProvider(string connectionString)
    {
        _connectionString = connectionString;
    }
    //interface methods implementation...
}
及服务登记册:

services.AddSingleton<ICacheProvider, RedisCacheProvider>();
services.AddSingleton();
如何将参数传递给RedisCacheProvider类的构造函数? 例如,对于Autofac:

builder.RegisterType<RedisCacheProvider>()
       .As<ICacheProvider>()
       .WithParameter("connectionString", "myPrettyLocalhost:6379");
builder.RegisterType()
.As()
.WithParameter(“connectionString”,“myPrettyLocalhost:6379”);

您可以提供一个委托来手动实例化缓存提供程序,也可以直接提供一个实例:

services.AddSingleton<ICacheProvider>(provider => new RedisCacheProvider("myPrettyLocalhost:6379"));

services.AddSingleton<ICacheProvider>(new RedisCacheProvider("myPrettyLocalhost:6379"));
services.AddSingleton(provider=>新的RedisCacheProvider(“myPrettyLocalhost:6379”);
AddSingleton(新的RedisCacheProvider(“myPrettyLocalhost:6379”);

请注意,容器不会显式地处理手动实例化的类型,即使它们实现IDisposable。有关更多信息,请参阅ASP.NET Core文档。如果构造函数也有依赖项,应该由DI解决,则可以使用:

公共类RedisCacheProvider:ICacheProvider
{
私有只读字符串_connectionString;
私有只读IMyInterface\u myImplementation;
公共RedisCacheProvider(字符串连接字符串,IMyInterface myImplementation)
{
_connectionString=connectionString;
_myImplementation=myImplementation;
}
//接口方法实现。。。
}
Startup.cs:

services.AddSingleton<IMyInterface, MyInterface>();
services.AddSingleton<ICacheProvider>(provider => 
    RedisCacheProvider("myPrettyLocalhost:6379", provider.GetService<IMyInterface>()));
services.AddSingleton();
services.AddSingleton(提供者=>
RedisCacheProvider(“myPrettyLocalhost:6379”,provider.GetService());

对参与方来说有点晚了,但是您可以DI注入一个工厂来创建并公开您的提供者类的实例。

您可以使用:

 services.AddSingleton<ICacheProvider>(x =>
      ActivatorUtilities.CreateInstance<RedisCacheProvider>(x, "myPrettyLocalhost:6379"));
services.AddSingleton(x=>
CreateInstance(x,“myPrettyLocalhost:6379”);

依赖项注入:ActivatorUtilities将向类注入任何依赖项。

您可以使用下面的示例代码

经理级:

public class Manager : IManager
{
    ILogger _logger;
    IFactory _factory;
    public Manager(IFactory factory, ILogger<Manager> logger)
    {
        _logger = logger;
        _factory = factory;
    }
}
公共类管理器:IManager
{
ILogger\u记录器;
工厂;;
公共经理(IFactory工厂、ILogger记录器)
{
_记录器=记录器;
_工厂=工厂;
}
}
Startup.cs类:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IFactory, Factory>(sp =>
    {
        var logger = sp.GetRequiredService<ILogger<Factory>>();
        var dbContext = sp.GetRequiredService<MyDBContext>();
        return new Factory(dbContext, logger);
    });
    services.AddTransient<IManager, Manager>(sp =>
    {
        var factory = sp.GetRequiredService<IFactory>();
        var logger = sp.GetRequiredService<ILogger<Manager>>();
        return new Manager(factory, logger);
    });
}
public void配置服务(IServiceCollection服务)
{
services.AddSingleton(sp=>
{
变量记录器=sp.GetRequiredService();
var dbContext=sp.GetRequiredService();
返回新工厂(dbContext、logger);
});
services.AddTransient(sp=>
{
var factory=sp.GetRequiredService();
变量记录器=sp.GetRequiredService();
返回新经理(工厂、记录器);
});
}

您可以在这里阅读完整的示例:

如果构造函数的参数是DbContext类型的变量,您将如何执行此操作。例如,
public类StateService:IStateService{private BloggingContext}上下文;public StateService(BloggingContext){{u context=context;}public IEnumerable List(){return\u context.States.ToList();}
@nam看看这个。它解释了如何添加作用域服务。简单实用不要忘记,如果您的服务采用了您注册的其他参数,那么您可以在注册时传递对服务的引用。e、 g.如果“RedisCacheProvider”也需要ISomeService,您可以这样做:services.AddSingleton(provider=>newRedisCacheProvider(“myPrettyLocalhost:6379”,provider.GetService())@Kévincharet如果您在回答中指定“手动实例化的类型”仅仅是通过
AddSingleton(T)
注册类型,那就太好了。从注册委托返回的类型(例如使用
AddSingleton(Func)
)实际上将被丢弃。我的通用解决方案: