Reputation: 16330
I've upgraded to the latest version of AutoMapper (9.0) and I've changed the static configuration to:
public static IMapper RegisterAutoMapper()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<MyModel MyDto>;
//etc...
});
var mapper = config.CreateMapper();
return mapper;
}
Using the previous static API I used to do the following in Global.asax
:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AutoMapping.Map();
}
WebApiConfig.Register
registers the routes and also Autofac
How do I register AutoMapper with Autofac because currently I'm getting compiler errors on such lines:
var myDto = Mapper.Map<MyModel>(model);
And the compiler error:
An object reference is required for the non-static field, method, or property 'Mapper.Map(object)'
Upvotes: 14
Views: 15718
Reputation: 9835
There is also a nuget-package that does all of that for you.
All you need to do is to call an extension method on the ContainerBuilder
and pass in the assemblies, that should be scanned for AutoMapper types.
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterAutoMapper(typeof(MvcApplication).Assembly);
// more registrations here
You can find it here. You can find an official example in the AutoMapper docs as well.
Edit: There are samples for ASP.NET Core and Console-Applications here.
Upvotes: 9
Reputation: 2416
This is an implmentation I applied to a Web API 2 project, in NET Framework 4.7.2, but despite how old it may look, you can use it too.
AutoMapper
- https://www.nuget.org/packages/AutoMapper/9.0.0Autofact
- https://www.nuget.org/packages/Autofac/6.4.0Autofact.WebAPI2
- https://www.nuget.org/packages/Autofac.WebApi2/6.1.1Notice second line. That's were you'll initialize the Autofact static class.
// Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
AutofacConfig.RegisterComponents(); // IoC, AUTOFAC
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
#region MAPPING
// AutofacConfig.cs
public static class AutofacConfig
{
public static void RegisterComponents()
{
var builder = new ContainerBuilder();
// Get your HttpConfiguration.
var config = GlobalConfiguration.Configuration;
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// OPTIONAL: Register the Autofac filter provider.
builder.RegisterWebApiFilterProvider(config);
// OPTIONAL: Register the Autofac model binder provider.
builder.RegisterWebApiModelBinderProvider();
#region MAPPING
// 1 - Mapper configuration is done here
// Notice the AutoMapperProfile instantiation
var mapperConfiguration = new MapperConfiguration(cfg => { cfg.AddProfile(new AutoMapperProfile()); });
// 2 - After configuring the mapper, you create it
var mapper = mapperConfiguration.CreateMapper();
// 3 - Register that instance of the mapper, which implements IMapper interface
builder.RegisterInstance<IMapper>(mapper);
// 4 - Now you register the TestMapper that you'll inject somewehre in your code, let's say, in a controller
// Register as many mappers as you need
builder.Register(c => new TestMapper(c.Resolve<IMapper>())).As<ITestMapper>();
#endregion
// Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
Profile
from AutoMapper
namespace.AutoMapperProfile
we did above.AutofacConfig.cs
// AutoMapperProfile.cs
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Test, TestDto>()
.ForMember(destination => destination.Floating, options => options.MapFrom(source => source.flotante))
.ForMember(dto => dto.Integer, opt => opt.MapFrom(src => src.entero))
;
// Test is a model/entity from the DB
// TestDto is a class I use as a Data Transfer Object
}
}
TestMapper
.ITestMapper
is your custom definition.// TestMapper.cs
public class TestMapper : ITestMapper
{
IMapper _mapper;
public TestMapper(IMapper mapper)
{
_mapper = mapper;
}
public TestDto GetTestItem(Test test)
{
return _mapper.Map<TestDto>(test);
}
// You may add additional implementation here.
}
TestMapper
as ITestMapper
wherever you may need it.ApiController
inheritor.// TestController.cs
[RoutePrefix("api/test")]
public class TestController : ApiController
{
private ITestMapper _testMapper;
public TestController(, ITestMapper testMapper)
{
_testMapper = testMapper;
}
[HttpGet]
[Route("GetTestItem/{id:int}")]
// GET api/<controller>/GetTestItem/5
public Prueba GetTestItem(int id)
{
var itemDb = _testRepository.GetTestItem(id); // it could be a service
var itemDto = _testMapper.GetTestItem(itemDb)
// Return the mapped object
return itemDto;
}
}
Upvotes: 3
Reputation: 2008
Here's one I made earlier:
public class YourAutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//Also register any custom type converter/value resolvers
builder.RegisterType<CustomValueResolver>().AsSelf();
builder.RegisterType<CustomTypeConverter>().AsSelf();
builder.Register(context => new MapperConfiguration(cfg =>
{
cfg.CreateMap<MyModel MyDto>;
//etc...
})).AsSelf().SingleInstance();
builder.Register(c =>
{
//This resolves a new context that can be used later.
var context = c.Resolve<IComponentContext>();
var config = context.Resolve<MapperConfiguration>();
return config.CreateMapper(context.Resolve);
})
.As<IMapper>()
.InstancePerLifetimeScope();
}
}
In the global.asax.cs
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyAutofacModule>();
// Register anything else needed
var container = builder.Build();
// MVC resolver
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// API Resolver
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
Then all you need to do is inject IMapper
Upvotes: 16
Reputation: 29
While I'm not familiar with Autofac myself, here is a recent article that descibes how to set up injection for automapper with Autofac.
Goodluck!
Upvotes: 0