Introduction.
We would create profile dynamically using reflection and using Autofac we would inject the auto-mapper.
Problem
When we create a lot of profiles. We need to add them in the configuration file as shown below.
Example.
public IMapper ConfigureMapper()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<Employee>();
cfg.AddProfile<Author>();
cfg.AddProfile<Title>();
.
.
.
.
.
.
.
.
.
.
cfg.AddProfile<Book>();
.
.
//30 more profiles
.
.
//30 more profiles
});
return config.CreateMapper();
}
As the project size grows adding the profiles become tedious and maintainability takes a hit.
As the project size grows adding the profiles become tedious and maintainability takes a hit.
Solution
We would create the profile and them dynamically using reflection code and use Autofac to inject them.
By creating auto-mapper profiles dynamically what do we achieve.
1.Open Closed Principle is not violated.
2.Developers would not add any profiles manually.
2.Developers would not add any profiles manually.
3.Code is neatly maintained.
So let’s achieve the same.
Step 1.Create a Common Library in the solution which would be
referred by all the other projects in the application.
Step 2.Create a class in Common Library called Auto Mapper Profile which extends a
base class “Profile” which is under the auto-mapper dll
public class AutoMapperProfile: Profile
{
}
3.Now the next step we would create required profiles which
extends “AutoMapperProfile” so you would create profiles as given below.
public class EmployeeProfile : AutoMapperProfile
{
public EmployeeProfile()
{
CreateMap<Employee, EmployeeModel>();
}
}
Note : If any Profiles that do not extend AutoMapperProfile class then the code would not work.
Step 3.We then need to add the AutoMapperConfiguration class. Where
we create a Method that returns IMapper.
In the above code we have used the reflection to find all the profiles where "AutoMapperProfile" class is extended
If you closely observe in the above code we have used ForEach. We have created an Enumerable extension which create an actionable item for each found profile.
public class AutoMapperConfiguration
{
public IMapper Configure()
{
var profiles =AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(a => typeof(AutoMapperProfile).IsAssignableFrom(a));
// Initialize AutoMapper with each instance of the profiles found.
var mapperConfiguration = new MapperConfiguration(a => profiles.ForEach(a.AddProfile));
return mapperConfiguration.CreateMapper();
}
}
In the above code we have used the reflection to find all the profiles where "AutoMapperProfile" class is extended
If you closely observe in the above code we have used ForEach. We have created an Enumerable extension which create an actionable item for each found profile.
public static class EnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> enumerable,
Action<T> action)
{
foreach (T item in enumerable) { action(item); }
}
}
Step 4: Once we are done with the Creating the Mapper we will return the IMapper to the Autofac object where we create instance for the mapper.
//Creating
an Instance for the Mapper
builder.RegisterInstance(new AutoMapperConfiguration().Configure()).As<IMapper>();
Step 5: After doing the above steps register the Auto-mapper in the
Autofac.
//Creating
an Instance for the Mapper
builder.RegisterInstance(new AutoMapperConfiguration().Configure()).As<IMapper>();
Step 6:To use the Automapper in the Project just Inject the
IMapper in the constructor and it works automatically.
public EmployeeManager(IEmployeeLogic employeelogic, IMapper mapper)
{
if (employeelogic==
null) throw new ArgumentNullException(nameof(employeelogic));
_employeelogic = employeelogic;
if (mapper == null) throw new ArgumentNullException(nameof(mapper));
_mapper = mapper;
}
private async Task<EmployeeModel>
GetEmployeeModel(Employee employee)
{
var employeeInfoModel = await _exampleCode.GetEmployeeRepo(employee);
return _mapper.Map<EmployeeModel>(employeeInfoModel );
}
Just follow the above steps and everything would work
seemelesly.
Code is available in the below repository.
https://github.com/BatIronMan007/AutoMapperReflection
Code is available in the below repository.
https://github.com/BatIronMan007/AutoMapperReflection