无法使用 ASP.NET Core DI 注入委托
Can't inject a delegate using ASP.NET Core DI
假设我有一个像这样的 MVC 核心控制器:
public class SomeController
{
public SomeController(IConfiguration appConfig, Func<string> someDelegate)
{
}
}
此外,我正在使用 AutoFac 来解决 注射。对象注入工作完美,而添加委托注入会产生一个 ASP.NET 核心异常,该异常表明 Func<string>
无法注入,因为没有可注入此类类型的组件。
当我尝试使用 AutoFac 手动解析 SomeController
时,我得到了所需的行为。
有没有办法在不使用 AutoFac 解析控制器的情况下支持这种情况?
控制器默认不通过 DI 解析,它们是在 DefaultControllerFactory
左右构造的。
更新
Microsoft.Extensions.DependencyInjection
不支持命名组件、发现、自动注册、装饰器等
它意味着开箱即用的简单 IoC,并为基本应用程序的 DI 提供基础,并为集成第 3 方 IoC 容器(具有自动发现、装饰器等高级功能)提供简单的方法(基本上他们所需要的只是处理 IServiceCollection
中的信息和 return 他们自己从 Configure
方法实现的 IServiceProvider
。
标签助手、控制器和视图组件在这方面是不同的,因为它们有自己的激活器(默认激活器使用激活实用程序,在某些时候进一步使用服务提供者)。出于这个原因 AddControllersAsServices
存在,因为它取代了 DefaultControllerActivator
(它使用 ActivationUtilities,参见 DefaultControllerActivator.cs) with ServiceBasedActivator
(which uses IServiceProvider
, see ServiceBasedControllerActivator
)。
有关如何通过 DI 解析控制器、标签助手和查看组件的详细信息,另请参阅 this related answer。
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);
代理可以这样注册:
var builder = services
.AddSingleton<ISomeService, SomeService>()
.AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));
假设我有一个像这样的 MVC 核心控制器:
public class SomeController
{
public SomeController(IConfiguration appConfig, Func<string> someDelegate)
{
}
}
此外,我正在使用 AutoFac 来解决 注射。对象注入工作完美,而添加委托注入会产生一个 ASP.NET 核心异常,该异常表明 Func<string>
无法注入,因为没有可注入此类类型的组件。
当我尝试使用 AutoFac 手动解析 SomeController
时,我得到了所需的行为。
有没有办法在不使用 AutoFac 解析控制器的情况下支持这种情况?
控制器默认不通过 DI 解析,它们是在 DefaultControllerFactory
左右构造的。
更新
Microsoft.Extensions.DependencyInjection
不支持命名组件、发现、自动注册、装饰器等
它意味着开箱即用的简单 IoC,并为基本应用程序的 DI 提供基础,并为集成第 3 方 IoC 容器(具有自动发现、装饰器等高级功能)提供简单的方法(基本上他们所需要的只是处理 IServiceCollection
中的信息和 return 他们自己从 Configure
方法实现的 IServiceProvider
。
标签助手、控制器和视图组件在这方面是不同的,因为它们有自己的激活器(默认激活器使用激活实用程序,在某些时候进一步使用服务提供者)。出于这个原因 AddControllersAsServices
存在,因为它取代了 DefaultControllerActivator
(它使用 ActivationUtilities,参见 DefaultControllerActivator.cs) with ServiceBasedActivator
(which uses IServiceProvider
, see ServiceBasedControllerActivator
)。
有关如何通过 DI 解析控制器、标签助手和查看组件的详细信息,另请参阅 this related answer。
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);
代理可以这样注册:
var builder = services
.AddSingleton<ISomeService, SomeService>()
.AddTrasient<CreateSomething>(provider => key => new Something(provider.GetRequiredService<ISomeService>(), key));