Skip to content

Commit 38e7c24

Browse files
authored
Merge pull request #20 from agileobjects/blogs/AgileMapper1_7
AgileMapper 1.7 release blog
2 parents 215cb5c + 8798514 commit 38e7c24

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

_posts/2020-05-01-readableexpressions-v3.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ tags: [Expression Trees, ReadableExpressions, Debugging]
66
images_dir: '2020-05-01/'
77
---
88

9-
ReadableExpressions translates Expression trees to source code as an alternative to Visual Studio's
9+
_ReadableExpressions translates Expression trees to source code as an alternative to Visual Studio's
1010
Debug View. There's a set of [Debugger Visualizers]({{ site.re_viz }}) in the Visual Studio Marketplace,
11-
and [a NuGet package]({{ site.re_nuget }}) with the extension method which does all the magic.
11+
and [a NuGet package]({{ site.re_nuget }}) with the extension method which does all the magic._
1212

1313
ReadableExpressions version 3 provides various options to customise translation, and colourizes the
1414
visualizer source code view, adding light and dark themes.

_posts/2020-06-18-agilemapper-v1_7.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
layout: post
3+
title: AgileMapper v1.7 Released
4+
excerpt: AgileMapper 1.7 is now on NuGet with bug fixes, and some new options for configuring data sources.
5+
tags: [AgileMapper]
6+
images_dir: '2020-06-18/'
7+
---
8+
9+
_AgileMapper is a powerful and unopinionated object mapper for .NET 3.5+ and .NET Standard 1.0+. It
10+
flattens, unflattens, deep clones, merges, updates and projects queries. It works without configuration,
11+
but if needed, is highly and easily configurable._
12+
13+
AgileMapper 1.7 is now [on NuGet]({{ site.am_nuget }}) with bug fixes, and some new options for
14+
[configuring data sources]({{ site.am_docs }}/configuration/Member-Values).
15+
16+
## Configuring Complete Type Mappings
17+
18+
AgileMapper does a pretty good job of figuring out how to map a pair of types, but for times when
19+
types don't match up at all, complete mappings can now be configured. This configuration is applied
20+
by the mapper whenever the configured type pair is matched:
21+
22+
```csharp
23+
Mapper.WhenMapping
24+
.From<Address>().To<AddressDto>()
25+
.MapInstancesUsing((a, dto) => new AddressDto
26+
{
27+
Number = a.HouseNo,
28+
Line1 = a.Street,
29+
Line2 = a.Town,
30+
Line3 = a.City,
31+
Line4 = a.County,
32+
Postcode = a.PostalCode
33+
});
34+
```
35+
36+
## Alternate Data Sources
37+
38+
To map from a data source other than a source model's matching member, an alternate source can be
39+
configured. Again, this configuration is applied whenever the configured type pair is matched:
40+
41+
```csharp
42+
Mapper.WhenMapping
43+
.FromDictionariesWithValueType<ProductDto>()
44+
.Over<List<Product>>()
45+
.Map(ctx => ctx.Source.Values)
46+
.ToTargetInstead(); // <- not ToTarget()
47+
```
48+
49+
In this example AgileMapper's usual [Dictionary mapping]({{ site.am_docs }}/Dictionary-Mapping) is
50+
skipped, and the source Dictionary's `Values` collection is used to update the target `List<Product>`
51+
using [collection mapping]({{ site.am_docs }}/Collections) instead.
52+
53+
Note that `ToTargetInstead()` is different to `ToTarget()`:
54+
55+
```csharp
56+
Mapper.WhenMapping
57+
.FromDictionariesWithValueType<ProductDto>()
58+
.Over<List<Product>>()
59+
.Map(ctx => ctx.Source.Values)
60+
.ToTarget(); // <- not ToTargetInstead()
61+
```
62+
63+
With `ToTarget()`, the usual Dictionary mapping is performed, _followed_ by a collection mapping from
64+
`Dictionary.Values`.
65+
66+
## Sequential Data Sources
67+
68+
A set of data sources can now be applied to a target one after the other:
69+
70+
```csharp
71+
Mapper.WhenMapping
72+
.From<Customer>()
73+
.ToANew<CustomerViewModel>()
74+
.Map((c, vm) => new[] { c.HomeAddress })
75+
.Then.Map((c, vm) => new[] { c.WorkAddress })
76+
.Then.Map((c, vm) => c.AddressHistory)
77+
.To(vm => vm.AllAddresses);
78+
```
79+
80+
In this example the target view model's `AllAddresses` collection is populated first using the source
81+
`Customer`'s `HomeAddress`, then the `WorkAddress`, then the `AddressHistory` collection. Previously
82+
only one [non-conditional data source]({{ site.am_docs }}/configuration/Member-Values#conditional-data-sources)
83+
could be configured for a target member - this option enables multiple sources to be applied in sequence.
84+
85+
Please report any issues or suggestions [on GibHub]({{ site.am_github }}/issues). Happy mapping!

0 commit comments

Comments
 (0)