Search code examples
automapper.net-6.0autofac

Configure two instance of same type for different constructors in autofac


I'm developing an ASP.NET project using .NET 6, Autofac for dependency injection, and AutoMapper for object mapping. In my project, I have two services, A and B, each of which requires its own AutoMapper configuration.
I have configured AutoMapper in my Startup.cs for service A, using the following code:

var mappingConfigA = new MapperConfiguration(config =>
{
    config.AddProfile(new AMappingProfile());
});

IMapper mapperA = mappingConfigA.CreateMapper();

builder.RegisterInstance(mapperA).As<IMapper>().SingleInstance();

Now, I need to configure a separate IMapper for service B using autofac.json while keeping service A's configuration intact. I want to avoid using key filtering and instead use autofac.json to define the IMapper for service B.

I need help understanding how to correctly configure a separate AutoMapper profile for service B using autofac.json and ensure that it uses its own mapper configuration. Any insights or guidance would be greatly appreciated.


Solution

  • If you want to use two types of implementation for single interface, based on specific condition in wiring, and want to use configuration file only. you have to use key attribute in configuration file and add controller as service.

    I add some example in https://github.com/soroshsabz/TestSolution

    but for further explanation I add this example below

    My assumption is Controllers like below (Using KeyFilter)

    public HomeController(ILogger<HomeController> logger,
                          [KeyFilter(nameof(DummyA))]IDummyModel dummyModel)
    {
          _logger = logger;
          _dummyModel = dummyModel;
    }
    

    First of all, I write a simple Startup.cs for specify conditions of dependency loading, and write ConfigureServices and ConfigureContainer like below

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().AddControllersAsServices();
            }
    
            public void ConfigureContainer(ContainerBuilder builder)
            {
                var configurationBuilder = new ConfigurationBuilder();
                configurationBuilder.AddJsonFile("autofac.json");
                var autoFacConfigurationModule = new ConfigurationModule(configurationBuilder.Build());
    
                builder.RegisterModule(autoFacConfigurationModule);
    
                //var controllers = typeof(Startup).Assembly.GetTypes().Where(t => t.BaseType == typeof(ControllerBase)).ToArray(); // for api controller
                var controllers = typeof(Startup).Assembly.GetTypes().Where(t => t.BaseType == typeof(Controller)).ToArray(); // for mvc controller
                builder.RegisterTypes(controllers).WithAttributeFiltering();
            }
    

    Then I write some configuration like below

    {
      "components": [
        {
          "type": "AutofacHandyMVCTest.Models.DummyA, AutofacHandyMVCTest",
          "services": [
            {
              "type": "AutofacHandyMVCTest.Models.IDummyModel, AutofacHandyMVCTest",
              "key": "DummyA"
            }
          ],
          "instanceScope": "per-lifetime-scope"
        }
      ]
    }
    

    as you can see, if I want to load DummyA I just need to set key to DummyA in configuration file.


    References: