.NET Core的可选构造函数注入参数

时间:2017-11-03 13:00:26

标签: c# dependency-injection .net-core

在某些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

3 个答案:

答案 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%,但也许我错了。