在某些IoC容器中,可能在构造函数中具有容器无法实现的参数。这可以通过<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div id="renderAdded"></div>
<input placeholder="Type something" id="inputText" type="text">
<button> Add word</button>
库和Microsoft.Extensions.DependencyInjection
来实现吗?如果没有,这类问题的清洁解决方案是什么?
例如:
IServiceProvider
答案 0 :(得分:2)
通常情况下,我会在这种情况下手工创建工厂。
public class TheFactory
{
public TheFactory( SomeType fromContainer )
{
_fromContainer = fromContainer;
}
public IProduct Create( SomeOtherType notFromContainer ) => new TheProduct( _fromContainer, notFromContainer );
private readonly SomeType _fromContainer;
private class TheProduct : IProduct
{
// ...
}
}
如果您需要来自容器的每个产品依赖项,工厂的Create
必须解决它们。或者,在例如统一,工厂从容器中获得Func
。
答案 1 :(得分:0)
在您的示例中,您为serviceProvider
提供了运行时值 currentDependency
。应用程序组件在构造期间不应要求运行时数据,如here所述。解决方案是重构您的设计,如该文章中所述。
关于可选参数:
某些DI容器支持可选参数这一事实并不能成为使用它们的好习惯。事实上,注入构造函数参数永远不应该是可选的。
正如this文章中所述:
可选依赖项意味着在未提供依赖项时,对依赖项的引用将为null。空引用使代码复杂化,因为它们需要针对null-case的特定逻辑。调用者可以插入没有行为的实现,而不是传入空引用,即空对象模式的实现。
如果没有,这类问题的清洁解决方案是什么?
如前所述,即使使用实际支持可选构造函数依赖项的DI Container,Null Object pattern也是 的解决方案。
答案 2 :(得分:0)
是否有理由不这样做?遇到需要HttpContext
的情况,但是在初始化Web应用程序的过程中,不可避免地会打几个电话。由于它是在初始化期间,因此没有请求,因此也没有上下文。
顺便说一句,所有这些都是用于相当典型的数据库审核,因此显然您希望用户名用于用户进行的更改,但是在初始化过程中,它最终只能使用“ SYSTEM”或类似名称。所以...
public class CurrentHttpUserProvider : ICurrentUserProvider
{
public CurrentHttpUserProvider(IServiceProvider container)
{
var httpContext = container.GetService(typeof(HttpContext)); // just returns null if it can't be found...
if (httpContext != null)
CurrentUser = ((HttpContext)httpContext).User.Identity.Name;
else
CurrentUser = "SYSTEM";
}
public string CurrentUser { get; set; }
}
这似乎就像我只是将HttpContext作为构造函数参数注入时一样高效100%,但也许我错了。