Quick & dirty
Use the IServiceProvider
available to resolve the IMapper
instance and put it inside the Lazy
:
services.AddScoped(provider =>
{
var mapper = provider.GetService<IMapper>();
return new Lazy<IMapper>(mapper);
});
Future-proof
If you want a more future-proof solution, you can create a generic lazy service provider, that will allow you to inject any from your registered services wrapped in Lazy<T>
like Lazy<IMapper>
. But, be warned that open generic types are not validated during startup services validation.
services.AddTransient(typeof(Lazy<>), typeof(LazyServiceProvider<>));
The lazy service provider:
public class LazyServiceProvider<T> : Lazy<T>
where T : class
{
public LazyServiceProvider(IServiceProvider provider)
: base(() => provider.GetRequiredService<T>())
{
}
}
Final note
AutoMapper's extension method accepts an array of types being assembly marker types, not mapping profile types. An assembly marker type is a type used for scanning the type's origin assembly for all mapping profiles that are contained in that assembly. All types matching AutoMapper's criteria are later on registered in order to create the mapper. So if those three types:
services.AddAutoMapper(
typeof(ApiProfile),
typeof(DomainToViewModelProfile),
typeof(DomainToDomainProfile));
are in the same assembly (project), then it is redundant. Luckily for you, the authors of AutoMapper are selecting only distinct assemblies, so no harm done, but it is still a code smell. If you had a large solution with dozens of mapping profiles, this marker type approach becomes handy, as you only need to pass one type for an assembly containing mapping profiles. It doesn't even have to be a mapping profile, it can be just any type representing the assembly. So, if those three types are in the same assembly, you can pass only one of them, and it will work just as before:
services.AddAutoMapper(typeof(ApiProfile));
Assembly type scanning is also used in, for example, another great library called Scrutor, so it's not that weird or uncommon thing to do.