C# Can';t使用ASP.NET核心DI注入委托

C# Can';t使用ASP.NET核心DI注入委托,c#,dependency-injection,asp.net-core,delegates,inversion-of-control,C#,Dependency Injection,Asp.net Core,Delegates,Inversion Of Control,假设我有一个MVC核心控制器,如下所示: public class SomeController { public SomeController(IConfiguration appConfig, Func<string> someDelegate) { } } var builder = services .AddSingleton<ISomeService, SomeService>() .AddTrasient<

假设我有一个MVC核心控制器,如下所示:

public class SomeController
{
     public SomeController(IConfiguration appConfig, Func<string> someDelegate)
     {
     }
}
var builder = services
    .AddSingleton<ISomeService, SomeService>()
    .AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));
公共类控制器
{
公共SomeController(IConfiguration appConfig、Func someDelegate)
{
}
}
此外,我正在使用AutoFac解决注射问题。对象注入工作正常,而添加委托注入会产生ASP.NET核心异常,该异常表明无法注入
Func
,因为没有可注入此类类型的组件

当我尝试使用AutoFac手动解析
SomeController
时,我得到了所需的行为


在不使用AutoFac解析控制器的情况下,是否有任何方法支持此方案?

默认情况下,控制器不是通过DI解析的,它们是在
DefaultControllerFactory
中构造的

更新
Microsoft.Extensions.DependencyInjection
不支持命名组件、发现、自动注册、装饰器等

它是简单的开箱即用IoC,为基本应用程序的DI提供基础,并为第三方IoC容器(具有自动发现、装饰器等高级功能)的集成提供简单的方法(基本上,他们只需要处理
IServiceCollection
中的信息,并从
Configure
方法返回他们自己的
IServiceProvider
实现)

标记帮助程序、控制器和视图组件在这方面有所不同,因为它们有自己的激活器(默认的激活器使用激活实用程序,在管道下游的某个点使用服务提供者)因此,
AddControllerAsservices
存在,因为它将
DefaultControllerActivator
(使用ActivationUtility,请参阅)替换为
ServiceBasedActivator
(使用
IServiceProvider
,请参阅)

有关如何通过DI解析控制器、标记帮助程序和查看组件的详细信息,请参见

var builder = services
    .AddMvc()
    .AddControllersAsServices() // this one for your case
    .AddViewComponentsAsServices()
    .AddTagHelpersAsServices();

我自己也遇到了这个问题,所以我想我会与大家分享以供将来参考,因为我有一个案例,我想解决一个委托,但包括一个额外的库似乎太过分了

鉴于以下定义:

public interface ISomething { /*...*/ };
public interface ISomeService { /*...*/ }

public class SomeService : ISomeService { /*...*/ }

public class Something
{
    public Something(ISomeService service, string key) { /*...*/ }
}

// I prefer using a delegate for readability but you
// don't have to use one
public delegate ISomething CreateSomething(string key);
可以按如下方式注册代理:

public class SomeController
{
     public SomeController(IConfiguration appConfig, Func<string> someDelegate)
     {
     }
}
var builder = services
    .AddSingleton<ISomeService, SomeService>()
    .AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));
var builder=services
.AddSingleton()
.AddTrasient(provider=>key=>newsomething(provider.GetRequiredService(),key));

感谢您的努力,但请记住,我的Q中有这样一段文字:在不使用AutoFac解析控制器的情况下,是否有任何方法可以支持此场景?并且,除了将委托注入控制器的构造函数之外,您不需要使用
addControllerAsseServices
方法。首先,我不知道您的注册,因此它是even很难说是什么问题。可能您使用了一些
NamedParameter
,或者只在服务上注册,而不在Autofac上注册,或者以其他方式注册。
Func
是一个奇怪的委托,这意味着它总是解析一个字符串,因为它是无参数的。添加
addControllerAsservic还有什么问题es()
是的,这是一个命名组件。
Func
是一个基本的例子。实际情况可能是
Func
可能我的问答应该标记为dup。我在这几个小时做了一些调查,发现其他人问类似的问题。嗯,
Microsoft.Extensions.DependencyInjection
不支持命名组件、发现和自动重新生成注册、装饰等。这意味着简单,并为第三方IoC容器的DI提供基础,方便地连接。标记帮助程序、控制器和视图组件在这方面有所不同,因为它们有自己的激活器(默认使用激活实用程序,在某些情况下使用服务提供商)因此,
addControllerAsservices
存在(它将
DefaultControllerActivator
(ActivationUtilities)替换为
ServiceBasedActivator
(ServiceErrorVider)