p1eXu5.AutoProfile
11.1.4
dotnet add package p1eXu5.AutoProfile --version 11.1.4
NuGet\Install-Package p1eXu5.AutoProfile -Version 11.1.4
<PackageReference Include="p1eXu5.AutoProfile" Version="11.1.4" />
paket add p1eXu5.AutoProfile --version 11.1.4
#r "nuget: p1eXu5.AutoProfile, 11.1.4"
// Install p1eXu5.AutoProfile as a Cake Addin #addin nuget:?package=p1eXu5.AutoProfile&version=11.1.4 // Install p1eXu5.AutoProfile as a Cake Tool #tool nuget:?package=p1eXu5.AutoProfile&version=11.1.4
AutoProfile.
<em>Custom AutoMapper attributes and profiler.</em>
Package | Versions |
---|---|
p1eXu5.AutoProfile | |
p1eXu5.AutoProfile | |
p1eXu5.AutoProfile | |
p1eXu5.AutoProfile | |
p1eXu5.AutoProfile |
<br/>
Mapping configurations.
see test project for more examples
1. Using map configuration factory method:
<br/>
[MapTo(typeof(Model),
MapFactory = nameof(CreateMapMethod),
IncludeAllDerived = true,
ReverseMap = true,
IncludeAllDerivedForReverse = true)]
[MapFrom(typeof(Model2), MapFactory = nameof(CreateMapMethod))]
public class Dto
{
...
public IMappingExpression<Dto, Model> CreateMapMethod(IAutoProfile profile)
{
return
profile.Instance.CreateMap<Dto, Model>(MemberList.Source);
}
public static IMappingExpression<Model2, Dto> StaticCreateMapMethod(IAutoProfile profile)
{
return
profile.Instance.CreateMap<Model2, Dto>(MemberList.Source);
}
}
If factory method is located in other type use MapFactoryType
attribute property.
<br/>
2. Using reverse map factory configuration method:
<br/>
[MapTo( typeof(IApplicationUser),
IncludeAllDerived = true,
IncludeAllDerivedForReverse = true,
MapFactory = nameof(UserDtoBase.CreateMap),
ReverseMapFactory = nameof(UserDtoBase.CreateReverseMap))]
public class UserDtoBase
{
public IMappingExpression<UserDtoBase, IApplicationUser> CreateMap(DerivedAutoProfile profile)
{
return
profile.Instance.CreateMap<UserDtoBase, IApplicationUser>(MemberList.Source)
.ForMember(au => au.FirstName, opt => opt.MapFrom((dto, au) => TextCipherSet.Encrypt( dto.FirstName, profile.PassPhrase)))
.ForMember(au => au.LastName, opt => opt.MapFrom((dto, au) => TextCipherSet.Encrypt( dto.LastName, profile.PassPhrase)));
}
// expr and profile can have any order in parameters
public IMappingExpression<IApplicationUser, UserDtoBase> CreateReverseMap(
IMappingExpression<UserDtoBase, IApplicationUser> expr,
DerivedAutoProfile profile)
{
return
expr.ReverseMap()
.ForMember(dto => dto.FirstName, opt => opt.MapFrom((au, dto) => TextCipherSet.Decrypt( au.FirstName, profile.PassPhrase)))
.ForMember(dto => dto.LastName, opt => opt.MapFrom((au, dto) => TextCipherSet.Decrypt( au.LastName, profile.PassPhrase)));
}
}
<br/>
3. Ignoring property.
<br/>
Ignoring destination property:
<br/>
[MapFrom(typeof(IModelA))]
[MapFrom(typeof(Model) /*, ...*/)]
public class ViewModel
{
[Ignore]
public IList<string> RoleNames { get; set; } = default!;
}
<br/>
[MapTo(typeof(ModelA))]
public class ViewModel...
{
public IList<string> RoleNames { get; set; } = default!;
}
public class ModelA...
{
[Ignore]
public IList<string> RoleNames { get; set; } = default!;
}
<br/>
Ignoring source property:
<br/>
[MapTo(typeof(IModelA))]
public class ViewModel
{
[Ignore]
public IList<string> RoleNames { get; set; } = default!;
}
<br/>
[MapFrom(typeof(ModelA))]
public class ViewModel
{
public IList<string> RoleNames { get; set; } = default!;
}
public class ModelA
{
[Ignore]
public IList<string> RoleNames { get; set; } = default!;
}
<br/>
4. OppositeAttribute usage:
<br/>
[MapTo(typeof(IApplicationUser))]
[MapFrom(typeof(IApplicationUser))]
public class UserUpdateDto : UserDto, IEntityIdDto<string>
{
[Opposite(nameof(IApplicationUser.UserTools))]
public ICollection<EntityIdDto>? Tools { get; set; }
}
<br/>
<b>Warning! There is an workaround to use with immutable record:</b>
<br/>
Define private parameterless constructor
Add private init
public record RecordModel { private RecordModel() { } public RecordModel(string oppositeProp) : this() { this.OppositeProp = oppositeProp; } public string OppositeProp { get; private init; } }
<br/>
Usage cases
<br/>
1. Configure in the ASP.NET Core:
<br/>
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection -Version 11.0.0
builder.Services.AddAutoMapper(
(serviceProvider, cfg) =>
{
var logger = serviceProvider.GetRequiredService<ILogger<AutoProfile>>();
var profile = new AutoProfile(typeof(Model), logger);
cfg.AddProfile(profile.Configure());
},
new Type[0]);
<br/>
2. For testing of certain maps:
<br/>
public abstract class AutoMapperTestsBase
{
protected IMapper Mapper { get; private set; } = default!;
protected virtual ICollection<Type> MappingTypes { get; } = Array.Empty<Type>();
[OneTimeSetUp]
public void Initialize()
{
AutoProfile autoProfile = new AutoProfile(
MockLoggerFactories.GetMockILogger<AutoProfile>(TestContext.WriteLine).Object,
new AutoProfileOptions(ProcessMapAttributesFromAssembly: false));
foreach (var type in MappingTypes) {
autoProfile.CreateMaps(type);
}
var conf = new MapperConfiguration(cfg => cfg.AddProfile(autoProfile.Configure()));
conf.AssertConfigurationIsValid();
Mapper = conf.CreateMapper();
}
}
<br/>
Other known issuers & workarounds.
<br/>
When a collection is mapped with resolver additional configuration is needed or AssertConfigurationIsValid() is failed (Automapper 9.0.0 bug):
public IMappingExpression<ProjectDto, Project> CreateMap(IAutoProfile profile) { return profile.Instance.CreateMap<Dto, Model>(MemberList.Source) .ForMember(model => model.Collection, opt => opt.MapFrom(dto => dto.Collection)) .ForMember(model => model.Collection, opt => { opt.MapFrom<FooResolver, ICollection<FooType>?>(dto => dto.Collection); }); }
In some cases you'll have to use both MapTo and MapFrom attribute instead of using ReverseMap = true only or AssertConfigurationIsValid() is failed (Automapper 9.0.0 bug).
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- AutoMapper (>= 11.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.