Home > Net >  Mapster Dependency Injection via Autofac
Mapster Dependency Injection via Autofac

Time:09-17

As per Mapster documentation https://github.com/MapsterMapper/Mapster/wiki/Dependency-Injection I am supposed to do the following:

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

The following is my attempt to add the above configuration in our MVC 4 app using Autofac:

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. How to add singleton of config instance?
  2. Not sure if I added IMapper - ServiceMapper configuration properly and if InstancePerHttpRequest is equivalent to AddScoped?

CodePudding user response:

  1. How to add singleton of config instance?

In general, you register services as singletons using the fluent method SingleInstance(), e.g.:

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

Each component with a dependency on MySingleton will get the same instance passed. However, in your case, there is no need to tell Autofac to use a single instance, because you create the instance yourself without the help of Autofac (var config = new TypeAdapterConfig();). Just register this one instance and Autofac won't have any other choice than injecting it wherever its required:

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

Yes, it should work fine this way.

... and if InstancePerHttpRequest is equivalent to AddScoped?

Well, basically yes, but not entirely.

It is not that easy to map functionality from Microsoft.Extensions.DependencyInjection to Autofac. Autofac comes with a concept called lifetime scopes. It allows you to register components that will be unique for the life of a specific scope and won't be used once this scope ends (thus the name lifetime):

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

You may create lifetime scopes for whatever lifetime concept comes to your mind. In the world of web application frameworks, the most common lifetime concept is the concept of requests, so you could create a new lifetime scope for each request. In fact, the Autofac integrations for the respective frameworks work exactly this way, so you don't have to create the lifetime scopes on your own.

This works fine, as long as there is only a single lifetime concept in your application domain. Once you start to create lifetime scopes inside other lifetime scopes, you cannot define to which lifetime scope a component should be unique. That is why Autofac supports tagging of lifetime scopes. This way you can register a component to be unique only for lifetime scopes with a specific tag:

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

Now, for each lifetime scope created using the tag "MyScope" a new instance of MyComponent will be used, but other lifetime scopes may share the same instance. As you can read in the Autofac documentation, InstancePerHttpRequest() is just a convenience method for InstancePerMatchingLifetimeScope with a specific unique tag for HTTP requests:

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.

  • Related