【问题标题】:Correct usage of lifetime scope of Autofac in web api 2在 web api 2 中正确使用 Autofac 的生命周期范围
【发布时间】:2019-01-22 07:23:09
【问题描述】:

我是 autofac 的新手。我在我的新 web api 2 项目中使用它。以下是 Global.asax 的 Application_Start() 方法调用的我的 autofac 配置代码。我不确定我对 InstancePerRequest() 的使用是否正确。更重要的是,它甚至需要使用吗?或者,我应该使用其他选项,例如 InstancePerLifeTimeScopre() 或 InstancePerDependency()?无论我是否使用这些生命周期范围选项中的任何一个,在调试期间,它们都会产生相同的结果。

public class IocConfig
{
    //Autofac configuration
    public static void Configure()
    {
        ContainerBuilder builder = new ContainerBuilder();
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<DeliveryCode>().As<IDeliveryCode>() 
         .InstancePerRequest();
        builder.RegisterType<DeliveryContext>().As<IDeliveryContext>()
         .InstancePerRequest();
        builder.RegisterType<DeliveryStrategy>().As<IDeliveryStrategy>() 
         .InstancePerRequest();
        IContainer container = builder.Build();
        AutofacWebApiDependencyResolver resolver = new 
            AutofacWebApiDependencyResolver(container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;
    }
}

【问题讨论】:

  • 假设您的控制器有两个依赖项 - IBobICathyBob 也依赖于 ICathy。如果ICathy 注册为InstancePerDependency,则将创建Cathy 的两个实例。如果InstancePerLifeTimeScope,只会创建一个。哪个是对的?嗯,这取决于你想要 1 还是 2。

标签: c# autofac


【解决方案1】:

InstancePerDependency - 您为每个依赖项获得一个新对象。对象永远不会在客户端之间共享。我会说只有在需要时才使用它,因为它比其他的更慢并且使用更多的内存。但它是非常安全的,因为每个依赖都是一个私有对象。

InstancePerRequest - 你会为一个 web api 调用获得一个新对象。当您想为每个 api 调用创建一个新对象,然后在此特定 api 调用期间与所有其他对象共享它时,这很有用。

InstancePerLifeTimeScope - 这个类似于以前的,但更通用。您通常不需要这个,只需忽略即可。 :-)

SingleInstance - 这只会在全局范围内创建一个实例,在不同的 Web api 调用和所有内容之间共享。对于全球数据提供者、向他人提供“服务”的无状态类等很有用。

请注意,“每个依赖项”和“单个实例”是相反的。 “每个请求”介于两者之间,专为 web api 量身定制。 :-)

另外请注意,如果您尝试过它们并且它们的行为似乎相同,这可能是因为您的测试是错误的。但它也可能是事实 - 无状态服务可以注册为任何类型并且可以正常工作。如果您在其他注册类型适用的情况下使用每个依赖项,那么效率会降低。同样,在适合单例的情况下,使用每个请求的效率较低。但这只是优化。另一方面,如果您的类是有状态的,而您在实际需要单独的实例时错误地将其注册为单例,那么您的程序将出现错误的行为,这比优化不足是更大的问题。

【讨论】:

  • You normally don't need this, just ignore. :-) 不,不要。使用它而不是InstancePerRequest 因为它更通用。 stackoverflow.com/questions/12127000/…autofaccn.readthedocs.io/en/latest/lifetime/…What this means is that if you try to resolve components that are registered as instance-per-request but there’s no current request… you’re going to get an exception.
  • @mjwills 从技术上讲,你是对的。但是你真的认为初学者会需要它吗?我不这么认为。刚开始使用web api的人可以忽略它。但是感谢您的澄清,现在任何人都可以单击链接并阅读更多信息。 :-)
  • 我认为始终使用InstancePerLifeTimeScope 是一个好习惯。因此它将在 MVC、WebAPI 和 .NET Core 中工作。如果有一种方法总是有效(例如InstancePerLifeTimeScope),那么我会鼓励它——尤其是对于初学者。
  • 根据这篇优秀的文章,decompile.it/blog/2014/03/13/webapi-autofac-lifetime-scopesInstancePerDependency() 似乎是默认的。 Al Kepp 在上面解释说,虽然速度较慢,但​​它是最安全的。因此,我从我的代码中删除了 InstancePerRequest(),然后默认为 InstancePerDependency()。谢谢大家的投入!
【解决方案2】:

确定依赖项的生命周期实际上取决于应用程序的需求。例如,如果您有一个用于检索常量值的依赖项,则它可能最适合作为单例,以便在应用程序的整个生命周期中仅检索一次这些值。

如果您还没有,我建议您查看“控制范围和生命周期”中的 Autofac documentation。它很好地概述了实例范围类型(​​即InstancePerLifeTimeScope()InstancePerDependency())之间的差异以及它们的行为方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多