C# 简单注入器中实例的延迟创建

C# 简单注入器中实例的延迟创建,c#,.net,dependency-injection,inversion-of-control,simple-injector,C#,.net,Dependency Injection,Inversion Of Control,Simple Injector,我在项目中使用Simple Injector连接所有必需的依赖项,但我无法调用容器。请验证,因为它在实际的第一个请求之前为http配置创建了单例实例 public interface IConfiguration { } public class Configuration : IConfiguration { public Configuration() { var httpContext = HttpContext.Current; var h

我在项目中使用Simple Injector连接所有必需的依赖项,但我无法调用
容器。请验证
,因为它在实际的第一个请求之前为http配置创建了
单例
实例

public interface IConfiguration { }
public class Configuration : IConfiguration
{
    public Configuration()
    {
        var httpContext = HttpContext.Current;
        var httpRequest = currentHttpContext.Request;
        var httpRequestUrl = currentHttpRequest.Url;

        this.UriScheme = currentHttpRequestUrl.Scheme;
        this.UriHost = currentHttpRequestUrl.Host;
        this.UriPort = currentHttpRequestUrl.Port;
    }

    public string UriScheme { get; private set; }
    public string UriHost { get; private set; }
    public int UriPort { get; private set; }
}

public class ServiceA
{
    private readonly _configuration;

    public ServiceA(IConfiguration configuration) 
    {
        _configuration = configuration 
    }
}

public class ServiceB
{
    private readonly _configuration;

    public ServiceB(IConfiguration configuration) 
    {
        _configuration = configuration
    }
}
这是该场景的一个基本示例。我目前大约有60项服务,全部取决于
I配置

创建配置类时,需要进行所有配置

这就是我在容器中注册实例的方法

var container = new Container();

//container.RegisterSingleton<IConfiguration, Configuration>();

var lazy = new Lazy<InstanceProducer>(() =>
    Lifestyle.Singleton.CreateProducer(typeof(IConfiguration), typeof(Configuration), container));

container.Register<ServiceA>();
container.Register<ServiceB>();

container.Verify(); // Creates configuration class --> not desired
var container=newcontainer();
//container.RegisterSingleton();
var lazy=new lazy(()=>
创建生产者(typeof(IConfiguration)、typeof(Configuration)、container);
container.Register();
container.Register();
container.Verify();//创建配置类-->不需要
依照

因此,这里的技巧是在验证过程之后触发新的
InstanceProducer
实例的创建

我知道解决方法是使用
Lazy
InstanceCreator
,但我无法正确完成代码挂钩

编辑

配置
类没有依赖项。
Configuration
的问题在于它在
容器上被创建为一个
单例
。请验证
方法调用,此时
currentHttpRequest.Url
不是实际的Url


我想我可以将配置从构造函数移动到一个方法(例如
GetConfiguration
)并进行一些重构,但我很好奇,在问题的场景下,延迟实例创建是否可以实现,正如Mark Seemann在文章中解释的,注入构造函数应该简单可靠。他们不应该做任何可能导致它失败的事情。在构造函数中调用
HttpContext.Current
会使其不可靠,因为这可能会失败

除此之外,
配置
组件现在依赖于运行时数据(HttpContext.Current
是运行时数据),这是一个sin,如中所述

然而,您的问题的解决方案非常简单明了。只需将
配置
类更改为以下内容:

public sealed class Configuration : IConfiguration
{
    public string UriScheme => this.Url.Scheme;
    public string UriHost => this.Url.Host;
    public int UriPort => this.Url.Port;
    private Uri Url => HttpContext.Current.Request.Url;
}

这不仅简化了事情,还消除了您正在应用的、给您带来麻烦的反模式。您的构造函数现在非常简单,甚至不再存在了(再简单不过了)。现在,仅在构建对象图之后才请求运行时数据(从
HttpContext.Current
)。这使容器能够可靠地验证其配置。

请显示有关
配置的更多详细信息
类的哪些部分阻止创建它以及它有哪些依赖项。最好是展示一些真实的代码。此外,您阅读的内容中指出,应用程序组件的构造,如
配置
不应依赖于任何可能失败的东西,就像您的情况一样?@Steven:请参阅编辑的问题谢谢您的回答Steven。我完全同意我不应该在构造函数中有运行时数据。。。你的答案确实解决了
容器。验证
问题,但我仍然对
惰性
InstanceCreator
的动态以及如何应用它们来绕过
容器感到好奇。按照验证
这是一件小事,但我无法理解out@TMiNus这显然是一个复杂的结构你的情况。事实上,您的问题链接到的答案描述了一个非常特殊的异常,只有通过不可更改的遗留代码才能证明它是正确的。这种构造应该只在真正特殊的情况下使用。我的观点是,如果我在未来遇到特殊情况,我不能应用这种构造,我真的很喜欢Simple Injector,所以我将开始在我所有的项目中使用它,因此我认为在我面临类似的情况之前是一个时间问题scenario@TMiNus如果您遇到这种真正特殊的情况,请在此处或Github上发布一个新问题,并提供所有详细信息。每一个案例都需要自己的分析,都应该得到分析和具体的回答。