Skip to content

Commit f489895

Browse files
committed
fix: removes applyTo
1 parent 8e25428 commit f489895

7 files changed

Lines changed: 7 additions & 181 deletions

File tree

ProjectR.Sample/Controllers/ProductsController.cs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ActionResult<ProductDto> GetById(Guid id)
3232
}
3333

3434
var mapper = _mapperResolver.GetMapper<Product, ProductDto>();
35-
var productDto = product.Project<ProductDto, Product, ProductDtoMapper>();
35+
var productDto = mapper.Project(product);
3636
return Ok(productDto);
3737
}
3838

@@ -47,22 +47,5 @@ public IActionResult CreateProduct([FromBody] CreateProductDto createDto)
4747

4848
return CreatedAtAction(nameof(GetById), new { id = newProduct.Id }, _mapperResolver.GetMapper<Product, ProductDto>().Project(newProduct));
4949
}
50-
51-
[HttpPut("{id}")]
52-
public IActionResult UpdateProduct(Guid id, [FromBody] UpdateProductDto updateDto)
53-
{
54-
var productToUpdate = _products.Find(p => p.Id == id);
55-
if (productToUpdate == null)
56-
{
57-
return NotFound();
58-
}
59-
60-
_mapperResolver.GetMapper<Product, UpdateProductDto>().Apply(updateDto, productToUpdate);
61-
62-
_products.RemoveAll(p => p.Id == id);
63-
_products.Add(productToUpdate);
64-
65-
return NoContent();
66-
}
6750
}
6851
}

ProjectR.Tests/MapperRegistrationExtensionsTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ private class TestMapper : Mapper<TestEntity, TestDto>
1818
{
1919
public override TestDto Project(TestEntity source) => new TestDto();
2020
public override TestEntity Build(TestDto dto) => new TestEntity();
21-
public override void Apply(TestDto dto, TestEntity entityToUpdate) { }
2221
}
2322

2423
private class TestMapper2 : Mapper<TestEntity2, TestDto2>
2524
{
2625
public override TestDto2 Project(TestEntity2 source) => new TestDto2();
2726
public override TestEntity2 Build(TestDto2 dto) => new TestEntity2();
28-
public override void Apply(TestDto2 dto, TestEntity2 entityToUpdate) { }
2927
}
3028

3129
private abstract class AbstractMapper : Mapper<TestEntity, TestDto>

ProjectR.Tests/MapperResolverTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ private class TestMapper : Mapper<TestEntity, TestDto>
1717
{
1818
public override TestDto Project(TestEntity source) => new TestDto();
1919
public override TestEntity Build(TestDto dto) => new TestEntity();
20-
public override void Apply(TestDto dto, TestEntity entityToUpdate) { }
2120
}
2221

2322
[Fact]

ProjectR.Tests/MapperTests.cs

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ public override TestEntity Build(TestDto dto)
3636
Value = dto.Value
3737
};
3838
}
39-
40-
public override void Apply(TestDto dto, TestEntity entityToUpdate)
41-
{
42-
entityToUpdate.Name = dto.Name;
43-
entityToUpdate.Value = dto.Value;
44-
}
4539
}
4640

4741
private class TestMapperWithRefinement : Mapper<TestEntity, TestDto>
@@ -64,12 +58,6 @@ public override TestEntity Build(TestDto dto)
6458
};
6559
}
6660

67-
public override void Apply(TestDto dto, TestEntity entityToUpdate)
68-
{
69-
entityToUpdate.Name = dto.Name;
70-
entityToUpdate.Value = dto.Value;
71-
}
72-
7361
public override TestEntity BuildRefiner(TestEntity entity, TestDto dto)
7462
{
7563
entity.Name = entity.Name.ToUpper();
@@ -81,11 +69,6 @@ public override TestDto ProjectAsRefiner(TestDto dto, TestEntity entity)
8169
dto.Name = dto.Name.ToLower();
8270
return dto;
8371
}
84-
85-
public override void ApplyToRefiner(TestEntity entity, TestDto dto)
86-
{
87-
entity.Name = entity.Name.Trim();
88-
}
8972
}
9073

9174
[Fact]
@@ -132,22 +115,6 @@ public void ProjectAsRefiner_DefaultImplementation_ReturnsDtoUnchanged()
132115
result.Value.Should().Be(100); // Unchanged
133116
}
134117

135-
[Fact]
136-
public void ApplyToRefiner_DefaultImplementation_DoesNothing()
137-
{
138-
// Arrange
139-
var mapper = new TestMapper();
140-
var entity = new TestEntity { Name = "Test", Value = 42 };
141-
var dto = new TestDto { Name = "Different", Value = 100 };
142-
143-
// Act
144-
mapper.ApplyToRefiner(entity, dto);
145-
146-
// Assert
147-
entity.Name.Should().Be("Test"); // Unchanged
148-
entity.Value.Should().Be(42); // Unchanged
149-
}
150-
151118
[Fact]
152119
public void BuildRefiner_CustomImplementation_ModifiesEntity()
153120
{
@@ -181,22 +148,6 @@ public void ProjectAsRefiner_CustomImplementation_ModifiesDto()
181148
result.Name.Should().Be("different"); // Modified to lowercase
182149
result.Value.Should().Be(100);
183150
}
184-
185-
[Fact]
186-
public void ApplyToRefiner_CustomImplementation_ModifiesEntity()
187-
{
188-
// Arrange
189-
var mapper = new TestMapperWithRefinement();
190-
var entity = new TestEntity { Name = " test ", Value = 42 };
191-
var dto = new TestDto { Name = "Different", Value = 100 };
192-
193-
// Act
194-
mapper.ApplyToRefiner(entity, dto);
195-
196-
// Assert
197-
entity.Name.Should().Be("test"); // Trimmed
198-
entity.Value.Should().Be(42);
199-
}
200151
}
201152

202153
public class MapperExtensionsTests
@@ -232,28 +183,6 @@ public override TestEntity Build(TestDto dto)
232183
Value = dto.Value
233184
};
234185
}
235-
236-
public override void Apply(TestDto dto, TestEntity entityToUpdate)
237-
{
238-
entityToUpdate.Name = dto.Name;
239-
entityToUpdate.Value = dto.Value;
240-
}
241-
}
242-
243-
[Fact]
244-
public void Apply_Extension_UpdatesEntityAndReturnsIt()
245-
{
246-
// Arrange
247-
var dto = new TestDto { Name = "Updated", Value = 100 };
248-
var entity = new TestEntity { Name = "Original", Value = 50 };
249-
250-
// Act
251-
var result = dto.Apply<TestDto, TestEntity, TestMapper>(entity);
252-
253-
// Assert
254-
result.Should().BeSameAs(entity);
255-
result.Name.Should().Be("Updated");
256-
result.Value.Should().Be(100);
257186
}
258187

259188
[Fact]
@@ -288,26 +217,6 @@ public void Build_Extension_CreatesAndReturnsEntity()
288217
result.Value.Should().Be(42);
289218
}
290219

291-
[Fact]
292-
public void Apply_Extension_CreatesNewMapperInstance()
293-
{
294-
// Arrange
295-
var dto = new TestDto { Name = "Test", Value = 42 };
296-
var entity1 = new TestEntity { Name = "Original1", Value = 1 };
297-
var entity2 = new TestEntity { Name = "Original2", Value = 2 };
298-
299-
// Act
300-
var result1 = dto.Apply<TestDto, TestEntity, TestMapper>(entity1);
301-
var result2 = dto.Apply<TestDto, TestEntity, TestMapper>(entity2);
302-
303-
// Assert
304-
// Both operations should work independently
305-
result1.Name.Should().Be("Test");
306-
result1.Value.Should().Be(42);
307-
result2.Name.Should().Be("Test");
308-
result2.Value.Should().Be(42);
309-
}
310-
311220
[Fact]
312221
public void Project_Extension_CreatesNewMapperInstance()
313222
{

ProjectR.Tests/MapperTypeCacheTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@ private class TestMapper : Mapper<TestEntity, TestDto>
1515
{
1616
public override TestDto Project(TestEntity source) => new TestDto();
1717
public override TestEntity Build(TestDto dto) => new TestEntity();
18-
public override void Apply(TestDto dto, TestEntity entityToUpdate) { }
1918
}
2019

2120
private class TestMapper2 : Mapper<TestEntity2, TestDto2>
2221
{
2322
public override TestDto2 Project(TestEntity2 source) => new TestDto2();
2423
public override TestEntity2 Build(TestDto2 dto) => new TestEntity2();
25-
public override void Apply(TestDto2 dto, TestEntity2 entityToUpdate) { }
2624
}
2725

2826
private class NonMapperClass { }

ProjectR/Builders/CodeBuilder.cs

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public string BuildSource(INamedTypeSymbol mapperSymbol, MappingPlan projectAsPl
2222
}
2323
BuildProjectAsMethod(mapperSymbol, projectAsPlan);
2424
BuildBuildMethod(mapperSymbol, buildPlan);
25-
BuildApplyToMethod(mapperSymbol, applyToPlan);
2625
BuildFooter();
2726
return _sb.ToString();
2827
}
@@ -120,22 +119,6 @@ private void BuildBuildMethod(INamedTypeSymbol mapperSymbol, MappingPlan plan)
120119
_sb.AppendLine();
121120
}
122121

123-
private void BuildApplyToMethod(INamedTypeSymbol mapperSymbol, MappingPlan plan)
124-
{
125-
var sourceTypeName = plan.SourceType.ToDisplayString();
126-
var destTypeName = plan.DestinationType.ToDisplayString();
127-
BuildXmlDoc(mapperSymbol, "Apply");
128-
Indent(); _sb.AppendLine($"public override void Apply({sourceTypeName} source, {destTypeName} destination)");
129-
Indent(); _sb.AppendLine("{");
130-
_indentationLevel++;
131-
Indent(); _sb.AppendLine("if (source is null || destination is null) return;");
132-
_sb.AppendLine();
133-
GenerateMappingInstructions("source", "destination", plan, isApplyTo: true);
134-
Indent(); _sb.AppendLine("ApplyToRefiner(destination, source);");
135-
_indentationLevel--;
136-
Indent(); _sb.AppendLine("}");
137-
}
138-
139122
private void GenerateCreationBlock(string variableName, ITypeSymbol variableType, MappingPlan plan, string sourceVarName, bool isBuild = false)
140123
{
141124
Indent();
@@ -158,7 +141,7 @@ private void GenerateCreationBlock(string variableName, ITypeSymbol variableType
158141
_sb.AppendLine($"new {variableType.ToDisplayString()}");
159142
Indent(); _sb.AppendLine("{");
160143
_indentationLevel++;
161-
GenerateMappingInstructions(sourceVarName, null, plan, isApplyTo: false);
144+
GenerateMappingInstructions(sourceVarName, null, plan);
162145
_indentationLevel--;
163146
Indent(); _sb.AppendLine("}");
164147
break;
@@ -201,7 +184,7 @@ private string GetMethodArguments(IMethodSymbol method, CreationInfo creationInf
201184
return string.Join(", ", args);
202185
}
203186

204-
private void GenerateMappingInstructions(string sourceVar, string? destVar, MappingPlan plan, bool isApplyTo)
187+
private void GenerateMappingInstructions(string sourceVar, string? destVar, MappingPlan plan)
205188
{
206189
foreach (var instruction in plan.Instructions)
207190
{
@@ -231,21 +214,12 @@ private void GenerateMappingInstructions(string sourceVar, string? destVar, Mapp
231214
assignment = $"{composite.Destination.Name} = string.Format(\"{composite.Format}\", {sourceProps})";
232215
break;
233216
case NestedPropertyMapping nested:
234-
var nestedMethod = GetNestedMethodName(nested.Source.Type, nested.Destination.Type, isApplyTo);
235-
if (isApplyTo)
236-
{
237-
Indent();
238-
_sb.AppendLine($"this._{GetFieldName(nested.Mapper)}.{nestedMethod}({sourceVar}.{nested.Source.Name}, {destVar}.{nested.Destination.Name});");
239-
continue;
240-
}
217+
var nestedMethod = GetNestedMethodName(nested.Source.Type, nested.Destination.Type);
241218
assignment = $"{nested.Destination.Name} = this._{GetFieldName(nested.Mapper)}.{nestedMethod}({sourceVar}.{nested.Source.Name})";
242219
break;
243220
case CollectionPropertyMapping collection:
244-
if (!isApplyTo)
245-
{
246-
var elementMethod = GetNestedMethodName(GetCollectionElementType(collection.Source.Type), GetCollectionElementType(collection.Destination.Type), isApplyTo);
247-
assignment = $"{collection.Destination.Name} = {sourceVar}.{collection.Source.Name}?.Select(x => this._{GetFieldName(collection.ElementMapper)}.{elementMethod}(x)).ToList()";
248-
}
221+
var elementMethod = GetNestedMethodName(GetCollectionElementType(collection.Source.Type), GetCollectionElementType(collection.Destination.Type));
222+
assignment = $"{collection.Destination.Name} = {sourceVar}.{collection.Source.Name}?.Select(x => this._{GetFieldName(collection.ElementMapper)}.{elementMethod}(x)).ToList()";
249223
break;
250224
}
251225
if (!string.IsNullOrEmpty(assignment))
@@ -264,11 +238,10 @@ private string GetLambdaParameterName(LambdaExpressionSyntax lambda)
264238
return "";
265239
}
266240

267-
private string GetNestedMethodName(ITypeSymbol? sourceType, ITypeSymbol? destinationType, bool isApplyTo)
241+
private string GetNestedMethodName(ITypeSymbol? sourceType, ITypeSymbol? destinationType)
268242
{
269243
if (sourceType == null || destinationType == null) return "Project";
270244
bool sourceIsDto = sourceType.Name.EndsWith("Dto"), destIsDto = destinationType.Name.EndsWith("Dto");
271-
if (isApplyTo) return "Apply";
272245
if (!sourceIsDto && destIsDto) return "Project";
273246
if (sourceIsDto && !destIsDto) return "Build";
274247
return "Project";

ProjectR/Mapping/Mapper.cs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ public abstract partial class Mapper<TEntity, TDto>
2424
/// <returns>A new entity object instance.</returns>
2525
public abstract TEntity Build(TDto dto);
2626

27-
/// <summary>
28-
/// Applies the data from a dto object to an existing entity object.
29-
/// This implementation will be generated automatically based on modification policies.
30-
/// </summary>
31-
/// <param name="dto">The dto object containing the new data.</param>
32-
/// <param name="entityToUpdate">The existing entity object to update.</param>
33-
public abstract void Apply(TDto dto, TEntity entityToUpdate);
34-
3527
/// <summary>
3628
/// A factory method used by the entity generator to create a new entity object.
3729
/// This method can be overridden to provide a custom creation logic.
@@ -57,39 +49,13 @@ public abstract partial class Mapper<TEntity, TDto>
5749
/// <param name="entity">The entity object instance.</param>
5850
/// <returns>The refined dto object instance.</returns>
5951
public virtual TDto ProjectAsRefiner(TDto dto, TEntity entity) => dto;
60-
61-
/// <summary>
62-
/// A refinement method used by the entity generator to apply final adjustments to the entity object after applying updates from a dto.
63-
/// This method can be overridden to provide custom refinement logic.
64-
/// </summary>
65-
/// <param name="entity">The entity object instance created by the build process.</param>
66-
/// <param name="dto">The dto object instance.</param>
67-
/// <returns>The refined entity object instance.</returns>
68-
public virtual void ApplyToRefiner(TEntity entity, TDto dto) { }
6952
}
7053

7154
/// <summary>
7255
/// Provides extension methods for simplified mapping operations.
7356
/// </summary>
7457
public static class MapperExtensions
7558
{
76-
/// <summary>
77-
/// Applies the data from a dto object to an existing entity object using the specified mapper.
78-
/// This is a generic extension method that simplifies the process of updating a entity entity from a DTO.
79-
/// </summary>
80-
/// <typeparam name="TDto">The dto type (e.g., the DTO).</typeparam>
81-
/// <typeparam name="TEntity">The entity type (e.g., the Domain Entity).</typeparam>
82-
/// <typeparam name="TMapper">The specific mapper class inheriting from <see cref="Mapper{TSource, TDestination}"/>.</typeparam>
83-
/// <param name="dto">The dto object containing the new data.</param>
84-
/// <param name="entityToUpdate">The existing entity object to update.</param>
85-
/// <returns>The updated entity object instance.</returns>
86-
public static TEntity Apply<TDto, TEntity, TMapper>(this TDto dto, TEntity entityToUpdate)
87-
where TMapper : Mapper<TEntity, TDto>, new()
88-
{
89-
Mapper<TEntity, TDto> mapper = Activator.CreateInstance<TMapper>();
90-
mapper.Apply(dto, entityToUpdate);
91-
return entityToUpdate;
92-
}
9359

9460
public static TDto Project<TDto, TEntity, TMapper>(this TEntity entity)
9561
where TMapper : Mapper<TEntity, TDto>, new()

0 commit comments

Comments
 (0)