I have an entity that looks like this:
public class Author : BaseEntity
{
public virtual string Name { get; private set; }
public virtual Address PhysicalAddress { get; private set; }
[JsonIgnore]
[IgnoreDataMember]
[ForeignKey("Recipe")]
public virtual Guid RecipeId { get; private set; }
public virtual Recipe Recipe { get; private set; }
public static Author Create(AuthorForCreationDto authorForCreationDto)
{
new AuthorForCreationDtoValidator().ValidateAndThrow(authorForCreationDto);
var config = new TypeAdapterConfig();
config.Apply(new AuthorProfile());
var mapper = new MapsterMapper.Mapper(config);
var newAuthor = mapper.Map<Author>(authorForCreationDto);
newAuthor.QueueDomainEvent(new AuthorCreated(){ Author = newAuthor });
return newAuthor;
}
public void Update(AuthorForUpdateDto authorForUpdateDto)
{
new AuthorForUpdateDtoValidator().ValidateAndThrow(authorForUpdateDto);
var config = new TypeAdapterConfig();
config.Apply(new AuthorProfile());
var mapper = new MapsterMapper.Mapper(config);
mapper.Map(authorForUpdateDto, this);
QueueDomainEvent(new AuthorUpdated(){ Id = Id });
}
protected Author() { } // For EF + Mocking
}
The problem is, if When I set up my mapper (below) and try to create an Author, I can't because I don't have a default constructor
public class AuthorProfile : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.NewConfig<string, PostalCode>()
.MapWith(src => new PostalCode(src));
config.NewConfig<PostalCode, string>()
.MapWith(src => src.Value);
config.NewConfig<Address, AddressDto>()
.TwoWays();
config.NewConfig<AddressForCreationDto, Address>()
.MapWith(src => new Address(src.Line1, src.Line2, src.City, src.State, src.PostalCode, src.Country))
.TwoWays();
config.NewConfig<AddressForUpdateDto, Address>()
.MapWith(src => new Address(src.Line1, src.Line2, src.City, src.State, src.PostalCode, src.Country))
.TwoWays();
config.NewConfig<Author, AuthorDto>()
.TwoWays();
config.NewConfig<AuthorForCreationDto, Author>()
.TwoWays();
config.NewConfig<Author, AuthorForUpdateDto>()
.TwoWays();
}
}
Error:
----> System.InvalidOperationException : No default constructor for type 'Author', please use 'ConstructUsing' or 'MapWith'
But then, when I try and use 'ConstructUsing' or 'MapWith'
config.NewConfig<AuthorForCreationDto, Author>()
.ConstructUsing(x => Author.Create(x));
I get an error, presumably because it is recursively trying to use a mapping inside the creation factory and using the factory for the mapping.
Exit code is 134 (Output is too long. Showing the last 100 lines:
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
On top of that, I don't even have a good option for something like the Update
since the creation factory uses an Update
dto and not a creation (though it could theoretically map one to the other?).
config.NewConfig<Author, AuthorForUpdateDto>()
.ConstructUsing(x => Author.Create(x))
Has anyone ran into this before? Any thoughts on potential solutions, other than manually mapping in the factories and using the above for all other maps?