哪种生活方式用于控制台应用?

Gra*_*ham 4 c# dependency-injection simple-injector

我有一个工作单元,它在Simple Injector中注册了一个由各种Web应用程序共享的通用程序集.

它注册为:

Container.Register(typeof(IUnitOfWork), typeof(UnitOfWork), new WebRequestLifestyle()); 
Run Code Online (Sandbox Code Playgroud)

我现在有一个控制台应用程序需要使用程序集中定义的容器,但显然无法使用WebRequestLifestyle.如果我尝试,我会收到以下错误:

IUnitOfWork被注册为"Web请求"生活方式,但实例是在Web请求的上下文之外请求的.

有没有我可以使用的替代方案WebRequestLifestyle,它将实现相同的功能,但对于Web和控制台应用程序?

Ste*_*ven 6

我可以使用WebRequestLifestyle的替代方案,它将实现相同的功能,但同时适用于Web和控制台应用程序?

就在这里.在Simple Injector v3中,建议的模式总是使用Lifestyle.Scoped:

Container.Register(typeof(IUnitOfWork), typeof(UnitOfWork), Lifestyle.Scoped);
Run Code Online (Sandbox Code Playgroud)

Lifestyle.Scoped是一种"占位符生活方式",映射到通过配置的范围生活方式Container.Options.DefaultScopedLifestyle.

这意味着在您的Web应用程序中,您将必须Container使用以下命令创建新实例:

var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
Run Code Online (Sandbox Code Playgroud)

这使得您的配置的其余部分无视给定的最终应用程序.

在您的控制台应用程序中,您通常应该使用AsyncScopedLifestyle.这意味着您的容器的创建在控制台应用程序中将如下所示:

var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
Run Code Online (Sandbox Code Playgroud)

AsyncScopedLifestyle可用于单线程和异步操作.它需要明确的管理.这意味着您必须在操作之前和之后手动启动和处置范围.如果您的控制台应用程序是短暂的,这通常意味着您在main方法中执行此操作:

void Main() 
{
    var container = BuildContainer();

    using (AsyncScopedLifestyle.BeginScope(container))
    {
        var service = container.GetInstance<MyRootType>();

        service.DoSomething();
    }

    container.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

如果控制台应用程序长(er)运行,它可能会处理多个自治请求(很像个别Web请求).在这种情况下,您将必须使用范围包装每个单独的请求(非常类似于上面的示例).

有关更多信息,请参阅文档.