Skip to content

Commit

Permalink
Continued work on migrating to mapperly
Browse files Browse the repository at this point in the history
  • Loading branch information
david-driscoll committed Aug 28, 2024
1 parent bd5a055 commit 6a87908
Show file tree
Hide file tree
Showing 23 changed files with 264 additions and 438 deletions.
4 changes: 1 addition & 3 deletions sample/Sample.BlazorServer/Pages/Rockets/Edit.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ public partial class Edit : ComponentBase

[Inject] private IMediator Mediator { get; set; } = null!;

[Inject] private IMapper Mapper { get; set; } = null!;

protected override async Task OnInitializedAsync()
{
Model = Mapper.Map<EditRocket.Request>(await Mediator.Send(new GetRocket.Request { Id = Id }));
Model = EditRocket.MapRequest(await Mediator.Send(new GetRocket.Request { Id = Id }));
}

public async Task Save()
Expand Down
14 changes: 6 additions & 8 deletions sample/Sample.Core/Models/LaunchRecordModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using NodaTime;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using StronglyTypedIds;

Expand Down Expand Up @@ -61,12 +60,11 @@ public partial record LaunchRecordModel
/// The kind of rocket that will be launching
/// </summary>
public RocketType RocketType { get; init; }

[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[UseStaticMapper(typeof(NodaTimeMapper))]
internal static partial class Mapper
{
public static partial LaunchRecordModel Map(LaunchRecord launchRecord);
}
}

internal static partial class ModelMapper
{
[MapperIgnoreSource(nameof(LaunchRecord.RocketId))]
public static partial LaunchRecordModel Map(LaunchRecord launchRecord);
public static partial IQueryable<LaunchRecordModel> ProjectTo(IQueryable<LaunchRecord> rocket);
}
12 changes: 12 additions & 0 deletions sample/Sample.Core/Models/ModelMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;

namespace Sample.Core.Models;

[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[UseStaticMapper(typeof(StandardMapper))]
[UseStaticMapper(typeof(NodaTimeMapper))]
internal static partial class ModelMapper
{
}
13 changes: 6 additions & 7 deletions sample/Sample.Core/Models/RocketModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ public record RocketModel
/// The type of the rocket
/// </summary>
public RocketType Type { get; init; }
}

[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Target)]
[UseStaticMapper(typeof(NodaTimeMapper))]
internal static partial class Mapper
{
[MapProperty(nameof(@ReadyRocket.SerialNumber), nameof(@RocketModel.Sn))]
public static partial RocketModel Map(ReadyRocket launchRecord);
}
internal static partial class ModelMapper
{
[MapProperty(nameof(@ReadyRocket.SerialNumber), nameof(@RocketModel.Sn))]
public static partial RocketModel Map(ReadyRocket rocket);
public static partial IQueryable<RocketModel> ProjectTo(IQueryable<ReadyRocket> rocket);
}
10 changes: 10 additions & 0 deletions sample/Sample.Core/Models/StandardMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Riok.Mapperly.Abstractions;

namespace Sample.Core;

[Mapper]
internal static partial class StandardMapper
{
public static long LongToDouble(double value) => Convert.ToInt64(value);
public static double DoubleToLong(long value) => Convert.ToDouble(value);
}
27 changes: 11 additions & 16 deletions sample/Sample.Core/Operations/LaunchRecords/CreateLaunchRecord.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
using FluentValidation;
using MediatR;
using NodaTime;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.LaunchRecords;

[PublicAPI]
public static class CreateLaunchRecord
[PublicAPI, Mapper(RequiredMappingStrategy = RequiredMappingStrategy.Source)]
[UseStaticMapper(typeof(NodaTimeMapper))]
[UseStaticMapper(typeof(ModelMapper))]
[UseStaticMapper(typeof(StandardMapper))]
public static partial class CreateLaunchRecord
{
/// <summary>
/// Create a launch record
Expand Down Expand Up @@ -57,18 +62,6 @@ public record Response
public LaunchRecordId Id { get; init; }
}

private class Mapper : Profile
{
public Mapper()
{
CreateMap<Request, LaunchRecord>()
.ForMember(x => x.RocketId, x => x.Ignore())
.ForMember(x => x.Rocket, x => x.Ignore())
.ForMember(x => x.Id, x => x.Ignore())
;
}
}

private class Validator : AbstractValidator<Request>
{
public Validator()
Expand All @@ -90,11 +83,13 @@ public Validator()
}
}

private class Handler(RocketDbContext dbContext, IMapper mapper) : IRequestHandler<Request, Response>
private static partial LaunchRecord Map(Request request);

private class Handler(RocketDbContext dbContext) : IRequestHandler<Request, Response>
{
public async Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
var record = mapper.Map<LaunchRecord>(request);
var record = Map(request);

var rocket = await dbContext.Rockets.FindAsync(new object[] { request.RocketId, }, cancellationToken);
if (rocket == null) throw new RequestFailedException("Rocket not found!");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using FluentValidation;
using MediatR;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.LaunchRecords;

[PublicAPI]
public static class DeleteLaunchRecord
[PublicAPI, Mapper]
[UseStaticMapper(typeof(NodaTimeMapper))]
public static partial class DeleteLaunchRecord
{
/// <summary>
/// The request to delete a launch record
Expand Down Expand Up @@ -47,4 +50,4 @@ public async Task Handle(Request request, CancellationToken cancellationToken)
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
}
}
}
56 changes: 26 additions & 30 deletions sample/Sample.Core/Operations/LaunchRecords/EditLaunchRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using NodaTime;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.LaunchRecords;

[PublicAPI]
[PublicAPI, Mapper]
[UseStaticMapper(typeof(NodaTimeMapper))]
[UseStaticMapper(typeof(ModelMapper))]
[UseStaticMapper(typeof(StandardMapper))]
public static partial class EditLaunchRecord
{
/// <summary>
Expand Down Expand Up @@ -58,17 +63,6 @@ public partial record Request : IRequest<LaunchRecordModel>
/// <param name="Id">The rocket id</param>
public partial record PatchRequest(LaunchRecordId Id) : IRequest<LaunchRecordModel>, IPropertyTracking<Request>;

private class Mapper : Profile
{
public Mapper()
{
CreateMap<Request, LaunchRecord>()
.ForMember(x => x.Rocket, x => x.Ignore())
.ForMember(x => x.Id, x => x.Ignore())
;
}
}

private class Validator : AbstractValidator<Request>
{
public Validator()
Expand Down Expand Up @@ -99,36 +93,38 @@ public Validator()
}
}

private class Handler(RocketDbContext dbContext, IMapper mapper, IMediator mediator)
[MapperIgnoreTarget(nameof(@LaunchRecord.Rocket))]
private static partial LaunchRecord Map(Request request);

[MapperIgnoreSource(nameof(@LaunchRecord.Rocket))]
private static partial Request Map(LaunchRecord model);

[MapperIgnoreTarget(nameof(@LaunchRecord.Rocket))]
private static partial void Map(Request request, LaunchRecord record);
private static Request Map(PatchRequest request, LaunchRecord record) => request.ApplyChanges(Map(record));

private class Handler(RocketDbContext dbContext, IMediator mediator)
: PatchRequestHandler<Request, PatchRequest, LaunchRecordModel>(mediator), IRequestHandler<Request, LaunchRecordModel>
{
private async Task<LaunchRecord> GetLaunchRecord(LaunchRecordId id, CancellationToken cancellationToken)
{
var rocket = await dbContext
.LaunchRecords
.Include(z => z.Rocket)
.FirstOrDefaultAsync(z => z.Id == id, cancellationToken)
.ConfigureAwait(false);
if (rocket == null) throw new NotFoundException();

return rocket;
}
private async Task<LaunchRecord> GetLaunchRecord(LaunchRecordId id, CancellationToken cancellationToken) => await dbContext
.LaunchRecords
.Include(z => z.Rocket)
.FirstOrDefaultAsync(z => z.Id == id, cancellationToken)
.ConfigureAwait(false)
?? throw new NotFoundException();

protected override async Task<Request> GetRequest(PatchRequest patchRequest, CancellationToken cancellationToken)
{
var rocket = await GetLaunchRecord(patchRequest.Id, cancellationToken);
return mapper.Map<Request>(mapper.Map<LaunchRecordModel>(rocket));
}
=> Map(patchRequest, await GetLaunchRecord(patchRequest.Id, cancellationToken));

public async Task<LaunchRecordModel> Handle(Request request, CancellationToken cancellationToken)
{
var rocket = await GetLaunchRecord(request.Id, cancellationToken);

mapper.Map(request, rocket);
Map(request, rocket);
dbContext.Update(rocket);
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

return mapper.Map<LaunchRecordModel>(rocket);
return ModelMapper.Map(rocket);
}
}
}
11 changes: 7 additions & 4 deletions sample/Sample.Core/Operations/LaunchRecords/GetLaunchRecord.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.LaunchRecords;

[PublicAPI]
public static class GetLaunchRecord
[PublicAPI, Mapper]
[UseStaticMapper(typeof(NodaTimeMapper))]
public static partial class GetLaunchRecord
{
/// <summary>
/// The request to get a launch record
Expand All @@ -31,7 +34,7 @@ public Validator()
}
}

private class Handler(RocketDbContext dbContext, IMapper mapper) : IRequestHandler<Request, LaunchRecordModel>
private class Handler(RocketDbContext dbContext) : IRequestHandler<Request, LaunchRecordModel>
{
public async Task<LaunchRecordModel> Handle(Request request, CancellationToken cancellationToken)
{
Expand All @@ -41,7 +44,7 @@ public async Task<LaunchRecordModel> Handle(Request request, CancellationToken c
.FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken);
if (rocket == null) throw new NotFoundException();

return mapper.Map<LaunchRecordModel>(rocket);
return ModelMapper.Map(rocket);
}
}
}
16 changes: 10 additions & 6 deletions sample/Sample.Core/Operations/LaunchRecords/ListLaunchRecords.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.LaunchRecords;

[PublicAPI]
public static class ListLaunchRecords
[PublicAPI, Mapper]
[UseStaticMapper(typeof(NodaTimeMapper))]
[UseStaticMapper(typeof(ModelMapper))]
[UseStaticMapper(typeof(StandardMapper))]
public static partial class ListLaunchRecords
{
/// <summary>
/// The launch record search
Expand All @@ -18,7 +23,8 @@ public record Request(RocketType? RocketType) : IStreamRequest<LaunchRecordModel

private class Validator : AbstractValidator<Request>;

private class Handler(RocketDbContext dbContext, IMapper mapper) : IStreamRequestHandler<Request, LaunchRecordModel>
private static partial IQueryable<LaunchRecordModel> Project(IQueryable<LaunchRecord> queryable);
private class Handler(RocketDbContext dbContext) : IStreamRequestHandler<Request, LaunchRecordModel>
{
public IAsyncEnumerable<LaunchRecordModel> Handle(Request request, CancellationToken cancellationToken)
{
Expand All @@ -28,9 +34,7 @@ public IAsyncEnumerable<LaunchRecordModel> Handle(Request request, CancellationT
.AsQueryable();
if (request.RocketType.HasValue) query = query.Where(z => z.Rocket.Type == request.RocketType);

return query
.ProjectTo<LaunchRecordModel>(mapper.ConfigurationProvider)
.ToAsyncEnumerable();
return Project(query).ToAsyncEnumerable();
}
}
}
26 changes: 11 additions & 15 deletions sample/Sample.Core/Operations/Rockets/CreateRocket.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
using FluentValidation;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Riok.Mapperly.Abstractions;
using Rocket.Surgery.LaunchPad.Foundation;
using Rocket.Surgery.LaunchPad.Mapping.Profiles;
using Sample.Core.Domain;
using Sample.Core.Models;

namespace Sample.Core.Operations.Rockets;

[PublicAPI]
public static class CreateRocket
[PublicAPI, Mapper]
[UseStaticMapper(typeof(NodaTimeMapper))]
[UseStaticMapper(typeof(ModelMapper))]
[UseStaticMapper(typeof(StandardMapper))]
public static partial class CreateRocket
{
/// <summary>
/// The operation to create a new rocket record
Expand Down Expand Up @@ -37,17 +42,6 @@ public record Response
public RocketId Id { get; init; }
}

private class Mapper : Profile
{
public Mapper()
{
CreateMap<Request, ReadyRocket>()
.ForMember(x => x.Id, x => x.Ignore())
.ForMember(x => x.LaunchRecords, x => x.Ignore())
;
}
}

private class Validator : AbstractValidator<Request>
{
public Validator()
Expand All @@ -62,7 +56,9 @@ public Validator()
}
}

private class Handler(RocketDbContext dbContext, IMapper mapper) : IRequestHandler<Request, Response>
[MapperRequiredMapping(RequiredMappingStrategy.Source)]
private static partial ReadyRocket Map(Request request);
private class Handler(RocketDbContext dbContext) : IRequestHandler<Request, Response>
{
public async Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
Expand All @@ -84,7 +80,7 @@ public async Task<Response> Handle(Request request, CancellationToken cancellati
},
};

var rocket = mapper.Map<ReadyRocket>(request);
var rocket = Map(request);
await dbContext.AddAsync(rocket, cancellationToken).ConfigureAwait(false);
await dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

Expand Down
Loading

0 comments on commit 6a87908

Please sign in to comment.