Luk*_*ien 9 c# dependency-injection asp.net-core
我在我自己的爱好项目中使用 ASP.NET Core,我想创建一个将由开发人员使用的框架,并且我想允许可选服务并使用未注册的默认值。
我收到Unable to resolve service for type 'XXX'错误,但我希望 DI 返回null而不是抛出异常。我想允许可选服务,因此如果找到服务,请在构造函数中使用它,如果未找到,则将 null 传递给构造函数。
在我的实现中,我有:
public IServiceManager(IService service, ...)
{
_service = service ?? new DefaultService();
...
}
Run Code Online (Sandbox Code Playgroud)
如您所见,如果找不到服务(空),请使用默认值。也许我误解了 DI 的工作原理。也许我可以使用工厂来代替它?但是,在我的系统中,当提供 non 时我使用默认服务将很常见,因此我需要一个不需要 API 使用者注册服务的解决方案。
有没有办法将 ASP.NET Core DI 配置为返回 null 而不是抛出异常?
lai*_*ika 18
在构造函数中为该参数添加默认值。
public IServiceManager(IService service = null, ...)
{
_service = service ?? new DefaultService();
...
}
Run Code Online (Sandbox Code Playgroud)
Tse*_*eng 13
就其本质而言,构造函数注入始终被认为是强制性的。
Microsoft DI 的第一个版本(我不喜欢使用术语 ASP.NET Core DI,因为它不依赖于 ASP.NET Core 并且可以在它之外使用)仅支持具有最多参数的构造函数。
我认为从那时起这已经发生了变化,允许多个构造函数,IoC 容器将选择一个合适的构造函数。话虽如此,您可能需要定义多个构造函数。
public IServiceManager(IService service, IOtherService otherService)
{
}
public IServiceManager(IOtherService otherService)
{
}
Run Code Online (Sandbox Code Playgroud)
如果IService没有在 IoC 容器中注册,则应调用第二个构造函数。
但这充其量仍然是一种值得怀疑的做法,并且会使您的代码更难维护和保持其不变/松散耦合。
你永远不应该在你的服务中实例化你的类型,即使是可选服务也是如此。
相反,您应该提供允许用户使用他们自己的实现覆盖它们的注册。
public static IServiceCollection AddMyLibrary(this IServiceCollection services)
{
services.TryAddTransient<IService, Service>();
services.TryAddTransient<IOtherService, OtherService>();
}
Run Code Online (Sandbox Code Playgroud)
然后用户覆盖它。
services.AddTransient<IService, CustomService>();
services.AddMyLibrary();
Run Code Online (Sandbox Code Playgroud)
现在CustomService将被注入到IService需要的地方。
| 归档时间: |
|
| 查看次数: |
6252 次 |
| 最近记录: |