Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/src/Collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ The following collection types are supported by default:
- `Collection<T>`
- `HashSet<T>`
- `ISet<T>`
- [`Dictionary<string, T>`](Dictionary-Mapping)
- [`IDictionary<string, T>`](Dictionary-Mapping)
- [`Dictionary<string, T>`](/Dictionary-Mapping)
- [`IDictionary<string, T>`](/Dictionary-Mapping)

Generic `List<T>` instances are created for interface-type members except `ISet<T>`, which uses a `HashSet<T>`. If a member is already populated with a non-readonly collection (e.g. an array), the existing object will be reused.

[Updates](Performing-Updates) and [merges](Performing-Merges) of collections of identifiable objects (i.e. Entities) are performed in an id-aware manner.
[Updates](/Performing-Updates) and [merges](/Performing-Merges) of collections of identifiable objects (i.e. Entities) are performed in an id-aware manner.

## Null Source Collections

Expand Down
14 changes: 0 additions & 14 deletions docs/src/Configuration.md

This file was deleted.

24 changes: 0 additions & 24 deletions docs/src/Configuring-Object-Identifiers.md

This file was deleted.

4 changes: 2 additions & 2 deletions docs/src/Derived-Types.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
For most cases, derived types are supported without configuration.
For many cases, derived type mapping is supported without configuration.

For example, with the following classes:

Expand Down Expand Up @@ -50,4 +50,4 @@ var resultAnimals = Mapper.Map(sourceAnimals).ToANew<AnimalDto[]>();
// resultAnimals[1] is of type DogDto
```

In the second example above, the `Dog` -> `DogDto` and `Cat` -> `CatDto` types are paired by convention based on the names of the original `Animal` -> `AnimalDto` pairing. You can configure [type pairs](Pairing-Derived-Types) which don't have a consistent naming convention, and [in which assemblies](Assembly-Scanning) to look for derived types.
In the second example above, the `Dog` -> `DogDto` and `Cat` -> `CatDto` types are paired by convention based on the names of the original `Animal` -> `AnimalDto` pairing. You can configure [type pairs](/configuration/Pairing-Derived-Types) which don't have a consistent naming convention, and [in which assemblies](/configuration/Assembly-Scanning) to look for derived types.
10 changes: 5 additions & 5 deletions docs/src/Dictionary-Mapping.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
AgileMapper has extensive support for mapping to and from Dictionaries. Out of the box:

* Only dictionaries with string keys are supported
* Dictionary keys must match target member names exactly, ignoring case ([configurable](Dictionary-Mapping-Configuration#configuring-keys))
* Parent and child member names are matched to dictionary keys separated with a dot ([configurable](Dictionary-Mapping-Configuration#configuring-separators)), or flattened - with no separator
* Enumerable elements are matched to dictionary keys by their index inside square brackets ([configurable](Dictionary-Mapping-Configuration#configuring-element-indexes))
* Dictionary keys must match target member names exactly, ignoring case ([configurable](/configuration/Dictionary-Mapping#configuring-keys))
* Parent and child member names are matched to dictionary keys separated with a dot ([configurable](/configuration/Dictionary-Mapping#configuring-separators)), or flattened - with no separator
* Enumerable elements are matched to dictionary keys by their index inside square brackets ([configurable](/configuration/Dictionary-Mapping#configuring-element-indexes))
* Dictionaries can contain all or a mixture of value type values, collections and complex types - anything with a matching key is used
* Target members with no matching key in the dictionary are ignored

Expand Down Expand Up @@ -49,7 +49,7 @@ The created `contactDetails` will have the following property values:
* "07890 654321" and
* "01234 987654"
* `Addresses` set to a new, 1-element `List<Address>` containing an `Address`:
* With `HouseNumber` set to '123' ([parsed](Type-Conversion) from the string)
* With `HouseNumber` set to '123' ([parsed](/Type-Conversion) from the string)
* With `StreetName` set to "Dictionary Street"

Note that the `StreetName` key had no separator, but the mapping works anyway.
Expand Down Expand Up @@ -91,4 +91,4 @@ The created `Dictionary` will have the following keys and values:

## Configuration

Dictionary mapping is [highly configurable](Dictionary-Mapping-Configuration).
Dictionary mapping is [highly configurable](/configuration/Dictionary-Mapping).
10 changes: 5 additions & 5 deletions docs/src/Dynamic-Mapping.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
AgileMapper's [dictionary mapping](Dictionary-Mapping) also applies to [ExpandoObject](https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.7.1)s, which are mapped using their `IDictionary<string, object>` interface.
AgileMapper's [dictionary mapping](/Dictionary-Mapping) also applies to [ExpandoObject](https://docs.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=netframework-4.7.1)s, which are mapped using their `IDictionary<string, object>` interface.

Out of the box:

* Member names must match target member names exactly, ignoring case ([configurable](Dynamic-Mapping-Configuration#configuring-member-names))
* Parent and child member names are matched to ExpandoObject member names separated with an underscore ([configurable](Dynamic-Mapping-Configuration#configuring-separators)), or flattened - with no separator
* Enumerable elements are matched to ExpandoObject member names by their index separated by underscores ([configurable](Dynamic-Mapping-Configuration#configuring-element-indexes))
* Member names must match target member names exactly, ignoring case ([configurable](/configuration/Dynamic-Mapping#configuring-member-names))
* Parent and child member names are matched to ExpandoObject member names separated with an underscore ([configurable](/configuration/Dynamic-Mapping#configuring-separators)), or flattened - with no separator
* Enumerable elements are matched to ExpandoObject member names by their index separated by underscores ([configurable](/configuration/Dynamic-Mapping#configuring-element-indexes))
* ExpandoObjects can contain all or a mixture of value type values, collections and complex types - anything with a matching member name is used
* Target members with no matching member in the ExpandoObject are ignored

Expand Down Expand Up @@ -89,4 +89,4 @@ The created `ExpandoObject` (in both cases) will have the following member names

## Configuration

Dynamic mapping is [highly configurable](Dynamic-Mapping-Configuration).
Dynamic mapping is [highly configurable](/configuration/Dynamic-Mapping).
2 changes: 1 addition & 1 deletion docs/src/Entity-Mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Mapping to entities - an object with a member decorated with a [`KeyAttribute`](

Members decorated with a `KeyAttribute` are not mapped, unless the mapping is a deep clone. Entity key values are usually generated by a data store, and some ORMs will throw an exception if a key value is updated in code.

If you need to map to a `KeyAttribute` member, you can override this behaviour by configuring a [custom data source](Configuring-Member-Values).
If you need to map to a `KeyAttribute` member, you can override this behaviour by configuring a [custom data source](/configuration/Member-Values).

### Optional Related Entity Keys

Expand Down
6 changes: 3 additions & 3 deletions docs/src/Enum-Mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Flags enums are mapped automatically from numeric, string, enum and character so

### Enum Mapping Mismatches

[Mapping plans](Using-Execution-Plans) warn you of enum mapping mismatches when mapping from one enum type to another. For example, a mapping between the following enums:
[Mapping plans](/Using-Execution-Plans) warn you of enum mapping mismatches when mapping from one enum type to another. For example, a mapping between the following enums:

```cs
// Source enum:
Expand All @@ -25,7 +25,7 @@ enum PaymentTypeUk { Cash, Card, Cheque }
// - PaymentTypeUs.Check matches no PaymentTypeUk
```

`PaymentTypeUk.Cheque` also mismatches, but the mapping is going from `PaymentTypeUs` -> `PaymentTypeUk`, and it only matters that all *source* values can be mapped to target values. This mismatch would cause an exception if you use [mapping validation](Validating-Mappings).
`PaymentTypeUk.Cheque` also mismatches, but the mapping is going from `PaymentTypeUs` -> `PaymentTypeUk`, and it only matters that all *source* values can be mapped to target values. This mismatch would cause an exception if you use [mapping validation](/Validating-Mappings).

## Configuring Enum Pairs

Expand All @@ -38,7 +38,7 @@ Mapper.WhenMapping

...which removes the enum mapping mismatch warning from the mapping plan, and stops the validation exception.

Enum pairing can also be configured [inline](Inline-Configuration):
Enum pairing can also be configured [inline](/configuration/Inline):

```cs
Mapper.Map(usTransaction).ToANew<UkTransaction>(cfg => cfg
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Mapping-Extension-Methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ customerDto.Map().OnTo(customer);

### Using an Instance-Scoped Mapper

Mappings performed via these extension methods use the default mapper - the same one you map with via the [static Mapper API](Static-vs-Instance-Mappers). To use an instance mapper with an extension method, use:
Mappings performed via these extension methods use the default mapper - the same one you map with via the [static Mapper API](/Static-vs-Instance-Mappers). To use an instance mapper with an extension method, use:

```cs
// Deep-clone a Customer using
Expand Down
4 changes: 2 additions & 2 deletions docs/src/Member-Matching.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
By default:

* Writable fields and properties, single-parameter methods prefixed with 'Set', constructor parameters and non-null, readonly complex type or enumerable members (except arrays) are targeted
* Target members are matched to [compatibly-typed](Type-Conversion) source members by name
* Target members are matched to [compatibly-typed](/Type-Conversion) source members by name
* Source members prefixed with 'Get' are matched without the prefix - [`GetHashCode`](https://msdn.microsoft.com/en-us/library/system.object.gethashcode%28v=vs.100%29.aspx) and [`GetType`](https://msdn.microsoft.com/en-us/library/system.object.gettype(v=vs.100).aspx) are ignored
* Members named `Id`, `<Type name>Id`, `Identifier` or `<Type name>Identifier` are matched
* Target members with no compatible source member are ignored.
Expand Down Expand Up @@ -37,7 +37,7 @@ public class Address
When mapping `CustomerViewModel` to `Customer`:

- `Customer.Name` is populated using `CustomerViewModel.Name`
- The `Customer.CustomerId` Guid is populated using the [parsed](Type-Conversion) `CustomerViewModel.Id` string
- The `Customer.CustomerId` Guid is populated using the [parsed](/Type-Conversion) `CustomerViewModel.Id` string
- `Customer.HomeAddress` is populated with a new `Address` instance if one does not already exist
- `Customer.HomeAddress.Line1` is populated using `CustomerViewModel.HomeAddressLine1`
- `Customer.WorkAddress` is get-only, so is ignored if it's null
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Meta-Members.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class AccountDto

- `FirstDeliveryAddressHasPostcode` - whether the first element in the source `DeliveryAddresses` collection has a non-default `Postcode` property value

Meta members are also supported in [query projections](Query-Projection).
Meta members are also supported in [query projections](/query-projection).

## Types of Meta Member

Expand Down
10 changes: 5 additions & 5 deletions docs/src/Object-Construction.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
AgileMapper constructs objects using [configured factories](Configuring-Object-Construction), factory methods and constructors, in that order.
AgileMapper constructs objects using [configured factories](/configuration/Object-Construction), factory methods and constructors, in that order.

### Factory Methods

A factory method will be used if:

- It's a public, static method returning an instance of the Type
- Its name starts with 'Create' or 'Get'
- All its parameters have [matching source values](Member-Matching)
- All its parameters have [matching source values](/Member-Matching)

### Constructors

A constructor will be used if:

- It's public
- All its parameters have [matching source values](Member-Matching)
- All its parameters have [matching source values](/Member-Matching)

### Selection Rules

- [Configured constructions](Configuring-Object-Construction) are preferred
- [Configured constructions](/configuration/Object-Construction) are preferred
- The factory method or constructor with the most parameters is preferred
- If a factory method has the same number of parameters as a constructor, the factory method is preferred
- If a factory method or constructor complex type argument would be passed as null, the next available factory method or constructor is used
- If there are no available factory methods or constructors with all-matched parameters - and no public, parameterless constructor - the member for which the object would be created is ignored
- To avoid infinite loops, if an object has a complex type constructor parameter of its own Type (a 'copy constructor'), it will be ignored.

If required, both [constructor parameters](Configuring-Constructor-Arguments) and [object construction](Configuring-Object-Construction) can be configured.
If required, both [constructor parameters](/configuration/Constructor-Arguments) and [object construction](/configuration/Object-Construction) can be configured.
6 changes: 3 additions & 3 deletions docs/src/Object-Flattening.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
AgileMapper matches flattened member names [as you'd expect](Member-Matching), but it also has a dedicated `.Flatten()` API which flattens objects in various ways. It is accessible:
AgileMapper matches flattened member names [as you'd expect](/Member-Matching), but it also has a dedicated `.Flatten()` API which flattens objects in various ways. It is accessible:

- Via the [static API](Static-vs-Instance-Mappers), using `Mapper.Flatten(myObject)`
- Via the [static API](/Static-vs-Instance-Mappers), using `Mapper.Flatten(myObject)`
- Via the instance API, using `myInstanceMapper.Flatten(myObject)`
- Via an [extension method](Mapping-Extension-Methods), using `myObject.Flatten()`
- Via an [extension method](/Mapping-Extension-Methods), using `myObject.Flatten()`

Flattening produces an object including all the source object's string or value-type members. For example:

Expand Down
8 changes: 4 additions & 4 deletions docs/src/Object-Unflattening.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
AgileMapper matches nested members to source members with flattened names [as you'd expect](Member-Matching), but it also has a dedicated `.Unflatten()` API which unflattens objects in various ways. It is accessible:
AgileMapper matches nested members to source members with flattened names [as you'd expect](/Member-Matching), but it also has a dedicated `.Unflatten()` API which unflattens objects in various ways. It is accessible:

- Via the [static API](Static-vs-Instance-Mappers), using `Mapper.Unflatten(myObject)`
- Via the [static API](/Static-vs-Instance-Mappers), using `Mapper.Unflatten(myObject)`
- Via the instance API, using `myInstanceMapper.Unflatten(myObject)`
- Via an [extension method](Mapping-Extension-Methods), using `myObject.Unflatten()`
- Via an [extension method](/Mapping-Extension-Methods), using `myObject.Unflatten()`

Unflattening produces an object populated using the source's [flattened](Object-Flattening) members.
Unflattening produces an object populated using the source's [flattened](/Object-Flattening) members.

For example, this Dictionary:

Expand Down
2 changes: 1 addition & 1 deletion docs/src/Performing-Merges.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Update an object's unpopulated members with values from another using:
Mapper.Map(customerViewModel).OnTo(customer);
```

When merging collections, objects are matched by id ([configurable](Configuring-Object-Identifiers) if necessary). For example:
When merging collections, objects are matched by id ([configurable](/configuration/Object-Identifiers) if necessary). For example:

```cs
var source = new Collection<CustomerViewModel>
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Performing-Updates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Update an object's members with values from another using:
Mapper.Map(customerViewModel).Over(customer);
```

When updating a collection, objects are matched by id ([configurable](Configuring-Object-Identifiers) if necessary). For example:
When updating a collection, objects are matched by id ([configurable](/configuration/Object-Identifiers) if necessary). For example:

```cs
var source = new[]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Static-vs-Instance-Mappers.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Using the static API enables mapping in less flexible scenarios where you aren't

### Instance API

Use the instance API via instance methods on an [`IMapper`](/agileobjects/AgileMapper/blob/master/AgileMapper/IMapper.cs) object, for example:
Use the instance API via instance methods on an [`IMapper`](https://github.com/agileobjects/AgileMapper/blob/master/AgileMapper/IMapper.cs) object, for example:

```cs
// Configuration - done once at start-up:
Expand Down
4 changes: 2 additions & 2 deletions docs/src/Type-Conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Value conversion is performed according to the following:

- Value types, nullable types and strings are all parsed and converted out of the box using the `TryParse` methods from the BCL.

- `DateTime`s (and nullable `DateTime`s) are converted to strings using `value.ToString(CultureInfo.CurrentCulture.DateTimeFormat)`. Custom formatting strings [can be configured](To-String-Formatting) for to-string conversions.
- `DateTime`s (and nullable `DateTime`s) are converted to strings using `value.ToString(CultureInfo.CurrentCulture.DateTimeFormat)`. Custom formatting strings [can be configured](/configuration/To-String-Formatting) for to-string conversions.

- Implicit or explicit to-String operators are used to convert values to strings where they are available.

Expand All @@ -23,6 +23,6 @@ target.EnumValue = source.Enum == SourceStatus.Complete
: default(TargetStatus)
```

&nbsp; &nbsp; &nbsp; &nbsp; ...any configured [enum pairs](Enum-Mapping#configuring-enum-pairs) are used as the first values in the tree.
&nbsp; &nbsp; &nbsp; &nbsp; ...any configured [enum pairs](/Enum-Mapping#configuring-enum-pairs) are used as the first values in the tree.

- Numerics are mapped to booleans (and vice-versa) with 1 mapping to true, and not-1 mapping to false.
8 changes: 4 additions & 4 deletions docs/src/Validating-Mappings.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
A mapper's [execution plans](Using-Execution-Plans) can be validated to ensure that:
A mapper's [execution plans](/Using-Execution-Plans) can be validated to ensure that:

- All target members have [matching](Member-Matching) source values
- All target complex types can either be [constructed](Object-Construction), or have mappable target members
- All members of any source [enums](Enum-Mapping) being mapped to target enums have matching members in the target enum type
- All target members have [matching](/Member-Matching) source values
- All target complex types can either be [constructed](/Object-Construction), or have mappable target members
- All members of any source [enums](/Enum-Mapping) being mapped to target enums have matching members in the target enum type

Mapping plan validation is intended to be used during development to make sure nothing is missed - you should remove it in production code.

Expand Down
Loading