通过 Autofac 进行 Mapster 依赖注入

Mapster Dependency Injection via Autofac

根据 Mapster 文档 https://github.com/MapsterMapper/Mapster/wiki/Dependency-Injection 我应该执行以下操作:

public void ConfigureServices(IServiceCollection services)
{
    ...
    var config = new TypeAdapterConfig();
    services.AddSingleton(config);
    services.AddScoped<IMapper, ServiceMapper>();
    ...
}

以下是我尝试使用 Autofac 在我们的 MVC 4 应用程序中添加上述配置:

public static void RegisterDependencies()
{
    var builder = new ContainerBuilder();

    ...

    var config = new TypeAdapterConfig();

    //services.AddSingleton(config); <- Not sure what is the equivalent of this line in Autofac?

    //services.AddScoped<IMapper, ServiceMapper>();
    // Not sure if the following is correct? Is AddScoped the same as InstancePerHttpRequest?
    builder.RegisterType<MapsterMapper.ServiceMapper>()
        .As<MapsterMapper.IMapper>()
        .InstancePerHttpRequest();
  1. 如何添加配置实例的单例?
  2. 不确定我是否正确添加了 IMapper - ServiceMapper 配置以及 InstancePerHttpRequest 是否等同于 AddScoped?
  1. How to add singleton of config instance?

一般情况下,您使用流畅的方法将服务注册为单例SingleInstance(),例如:

builder.RegisterType<MySingleton>().SingleInstance();

依赖于MySingleton的每个组件都将获得相同的实例传递。但是,在您的情况下,无需告诉 Autofac 使用单个实例,因为您在没有 Autofac (var config = new TypeAdapterConfig();) 帮助的情况下自己创建了实例。只需注册这个实例,Autofac 除了在需要的地方注入它之外别无选择:

builder.RegisterInstance(config);
  1. Not sure if I added IMapper - ServiceMapper configuration properly ...

是的,这样应该没问题。

... and if InstancePerHttpRequest is equivalent to AddScoped?

嗯,基本上是,但不完全是。

将功能从 Microsoft.Extensions.DependencyInjection 映射到 Autofac 并不容易。 Autofac 附带了一个名为 lifetime scopes 的概念。它允许您注册在特定范围的生命周期内唯一的组件,并且一旦该范围结束就不会被使用(因此名称 lifetime):

builder.RegisterType<MyComponent>().InstancePerLifetimeScope();

您可以为您想到的任何生命周期概念创建生命周期范围。在 Web 应用程序框架的世界中,最常见的生命周期概念是请求的概念,因此您可以为每个请求创建一个新的生命周期范围。事实上,各个框架的 Autofac 集成正是以这种方式工作的,因此您不必自己创建生命周期范围。

只要您的应用程序域中只有一个生命周期概念,这就可以正常工作。一旦开始在其他生命周期范围内创建生命周期范围,就无法定义组件在哪个生命周期范围内应该是唯一的。这就是 Autofac 支持标记生命周期范围的原因。通过这种方式,您可以将组件注册为仅在具有特定标签的生命周期范围内是唯一的:

builder.RegisterType<MyComponent>().InstancePerMatchingLifetimeScope("MyScope");

现在,对于使用标签 "MyScope" 创建的每个生命周期范围,将使用 MyComponent 的新实例,但其他生命周期范围可能共享同一个实例。正如您在 Autofac documentation 中所读到的,InstancePerHttpRequest() 只是 InstancePerMatchingLifetimeScope 的一种便捷方法,具有用于 HTTP 请求的特定唯一标记:

Instance per request builds on top of instance per matching lifetime scope by providing a well-known lifetime scope tag, a registration convenience method, and integration for common application types. Behind the scenes, though, it’s still just instance per matching lifetime scope.