diff --git a/docs/src/Collections.md b/docs/src/Collections.md index 3e4aacf9b..774b0291a 100644 --- a/docs/src/Collections.md +++ b/docs/src/Collections.md @@ -12,12 +12,12 @@ The following collection types are supported by default: - `Collection` - `HashSet` - `ISet` -- [`Dictionary`](Dictionary-Mapping) -- [`IDictionary`](Dictionary-Mapping) +- [`Dictionary`](/Dictionary-Mapping) +- [`IDictionary`](/Dictionary-Mapping) Generic `List` instances are created for interface-type members except `ISet`, which uses a `HashSet`. 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 diff --git a/docs/src/Configuration.md b/docs/src/Configuration.md deleted file mode 100644 index 1ef45757b..000000000 --- a/docs/src/Configuration.md +++ /dev/null @@ -1,14 +0,0 @@ -Many aspects of mapping can be configured, but no up-front type registration is required - a mapping function is created and cached the first time two types are mapped. - -Various configuration options are available: - -- [Static](Static-vs-Instance-Mappers) configuration (`Mapper.WhenMapping`) configures a default, instance-scoped mapper behind the scenes. This configures the mapper used when you call `Mapper.Map(source)` - -- [Instance](Static-vs-Instance-Mappers) configuration (`mapper.WhenMapping`) configures that particular instance - -- [Inline](Inline-configuration) configuration combines the configuration of the mapper performing the mapping with the inline configuration you supply - -- [Class](Configuration-Classes) configuration splits configuration up into dedicated configuration classes. - -The same API is available in all four contexts. - diff --git a/docs/src/Configuring-Object-Identifiers.md b/docs/src/Configuring-Object-Identifiers.md deleted file mode 100644 index 2216f2f9f..000000000 --- a/docs/src/Configuring-Object-Identifiers.md +++ /dev/null @@ -1,24 +0,0 @@ -Objects are identified during collection [updates](Performing-Updates) and [merges](Performing-Merges) using members with the following names: - -* `Id` -* `Id` -* `Identifier` -* `Identifier` - -You can configure an object to be uniquely identified with a different member using: - -```cs -Mapper.WhenMapping - .InstancesOf() // Apply to NamedCustomer mappings - .IdentifyUsing(c => c.Name); // Identify using NamedCustomer.Name -``` - -Or, configured [inline](Inline-Configuration): - -```cs -Mapper - .Map(customerDtos).ToANew(cfg => cfg - .WhenMapping - .InstancesOf() - .IdentifyUsing(c => c.Name)); // Identify using NamedCustomer.Name -``` \ No newline at end of file diff --git a/docs/src/Derived-Types.md b/docs/src/Derived-Types.md index abdb76266..89de45189 100644 --- a/docs/src/Derived-Types.md +++ b/docs/src/Derived-Types.md @@ -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: @@ -50,4 +50,4 @@ var resultAnimals = Mapper.Map(sourceAnimals).ToANew(); // 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. \ No newline at end of file +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. \ No newline at end of file diff --git a/docs/src/Dictionary-Mapping.md b/docs/src/Dictionary-Mapping.md index 4cb33a025..e59cb5011 100644 --- a/docs/src/Dictionary-Mapping.md +++ b/docs/src/Dictionary-Mapping.md @@ -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 @@ -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
` 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. @@ -91,4 +91,4 @@ The created `Dictionary` will have the following keys and values: ## Configuration -Dictionary mapping is [highly configurable](Dictionary-Mapping-Configuration). \ No newline at end of file +Dictionary mapping is [highly configurable](/configuration/Dictionary-Mapping). \ No newline at end of file diff --git a/docs/src/Dynamic-Mapping.md b/docs/src/Dynamic-Mapping.md index 08df84fdf..c0cb2d412 100644 --- a/docs/src/Dynamic-Mapping.md +++ b/docs/src/Dynamic-Mapping.md @@ -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` 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` 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 @@ -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). \ No newline at end of file +Dynamic mapping is [highly configurable](/configuration/Dynamic-Mapping). \ No newline at end of file diff --git a/docs/src/Entity-Mapping.md b/docs/src/Entity-Mapping.md index 6c7602f0a..f99be9e09 100644 --- a/docs/src/Entity-Mapping.md +++ b/docs/src/Entity-Mapping.md @@ -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 diff --git a/docs/src/Enum-Mapping.md b/docs/src/Enum-Mapping.md index 4fce7868b..2874538bb 100644 --- a/docs/src/Enum-Mapping.md +++ b/docs/src/Enum-Mapping.md @@ -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: @@ -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 @@ -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(cfg => cfg diff --git a/docs/src/Mapping-Extension-Methods.md b/docs/src/Mapping-Extension-Methods.md index 6cea0e21d..f134e1d42 100644 --- a/docs/src/Mapping-Extension-Methods.md +++ b/docs/src/Mapping-Extension-Methods.md @@ -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 diff --git a/docs/src/Member-Matching.md b/docs/src/Member-Matching.md index e6cf938a8..1af7d2d3a 100644 --- a/docs/src/Member-Matching.md +++ b/docs/src/Member-Matching.md @@ -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`, `Id`, `Identifier` or `Identifier` are matched * Target members with no compatible source member are ignored. @@ -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 diff --git a/docs/src/Meta-Members.md b/docs/src/Meta-Members.md index c0e9d72e7..ca882219d 100644 --- a/docs/src/Meta-Members.md +++ b/docs/src/Meta-Members.md @@ -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 diff --git a/docs/src/Object-Construction.md b/docs/src/Object-Construction.md index f6c5f53b4..f43cd5146 100644 --- a/docs/src/Object-Construction.md +++ b/docs/src/Object-Construction.md @@ -1,4 +1,4 @@ -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 @@ -6,22 +6,22 @@ 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. \ No newline at end of file +If required, both [constructor parameters](/configuration/Constructor-Arguments) and [object construction](/configuration/Object-Construction) can be configured. \ No newline at end of file diff --git a/docs/src/Object-Flattening.md b/docs/src/Object-Flattening.md index 5a01aee50..50240ef19 100644 --- a/docs/src/Object-Flattening.md +++ b/docs/src/Object-Flattening.md @@ -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: diff --git a/docs/src/Object-Unflattening.md b/docs/src/Object-Unflattening.md index fd71633ca..18a035e2a 100644 --- a/docs/src/Object-Unflattening.md +++ b/docs/src/Object-Unflattening.md @@ -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: diff --git a/docs/src/Performing-Merges.md b/docs/src/Performing-Merges.md index 5cfb37973..6f0742a99 100644 --- a/docs/src/Performing-Merges.md +++ b/docs/src/Performing-Merges.md @@ -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 diff --git a/docs/src/Performing-Updates.md b/docs/src/Performing-Updates.md index 9f6be6d65..3996eb321 100644 --- a/docs/src/Performing-Updates.md +++ b/docs/src/Performing-Updates.md @@ -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[] diff --git a/docs/src/Static-vs-Instance-Mappers.md b/docs/src/Static-vs-Instance-Mappers.md index e11a4b833..0662926fb 100644 --- a/docs/src/Static-vs-Instance-Mappers.md +++ b/docs/src/Static-vs-Instance-Mappers.md @@ -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: diff --git a/docs/src/Type-Conversion.md b/docs/src/Type-Conversion.md index 686eacf61..c75618ced 100644 --- a/docs/src/Type-Conversion.md +++ b/docs/src/Type-Conversion.md @@ -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. @@ -23,6 +23,6 @@ target.EnumValue = source.Enum == SourceStatus.Complete : default(TargetStatus) ``` -        ...any configured [enum pairs](Enum-Mapping#configuring-enum-pairs) are used as the first values in the tree. +        ...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. \ No newline at end of file diff --git a/docs/src/Validating-Mappings.md b/docs/src/Validating-Mappings.md index 28e850dea..3bddf68ae 100644 --- a/docs/src/Validating-Mappings.md +++ b/docs/src/Validating-Mappings.md @@ -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. diff --git a/docs/src/Assembly-Scanning.md b/docs/src/configuration/Assembly-Scanning.md similarity index 100% rename from docs/src/Assembly-Scanning.md rename to docs/src/configuration/Assembly-Scanning.md diff --git a/docs/src/Configuration-Classes.md b/docs/src/configuration/Classes.md similarity index 95% rename from docs/src/Configuration-Classes.md rename to docs/src/configuration/Classes.md index c9bad61b4..282b0495e 100644 --- a/docs/src/Configuration-Classes.md +++ b/docs/src/configuration/Classes.md @@ -1,4 +1,4 @@ -Multiple, dedicated configuration classes can be created by deriving from the abstract `MapperConfiguration` base class. This enables configuration to be split up and placed nearer where mapping is performed (although [inline](Inline-Configuration) is nearer). +Multiple, dedicated configuration classes can be created by deriving from the abstract `MapperConfiguration` base class. This enables configuration to be split up and placed nearer where mapping is performed (although [inline](/configuration/Inline) is nearer). `MapperConfiguration` provides the same configuration API, and exposes services you inject. @@ -26,7 +26,7 @@ public class ProductMappingConfiguration : MapperConfiguration } ``` -In this example the default mapper is configured - the one used via the [static](Static-vs-Instance-Mappers) Mapper API. +In this example the default mapper is configured - the one used via the [static](/Static-vs-Instance-Mappers) Mapper API. ### Applying Configurations @@ -98,7 +98,7 @@ Chains of `ApplyAfter` attributes will be followed, with all configurations auto ### Accessing Services -[Configured Service Providers](Dependency-Injection) are available to `MapperConfiguration` classes. For example: +[Configured Service Providers](/configuration/Dependency-Injection) are available to `MapperConfiguration` classes. For example: ```cs // Get a Dependency Injection container: diff --git a/docs/src/Cloning-Mappers.md b/docs/src/configuration/Cloning-Mappers.md similarity index 100% rename from docs/src/Cloning-Mappers.md rename to docs/src/configuration/Cloning-Mappers.md diff --git a/docs/src/Configuring-Constructor-Arguments.md b/docs/src/configuration/Constructor-Arguments.md similarity index 80% rename from docs/src/Configuring-Constructor-Arguments.md rename to docs/src/configuration/Constructor-Arguments.md index 36b586d9b..d6d6ed094 100644 --- a/docs/src/Configuring-Constructor-Arguments.md +++ b/docs/src/configuration/Constructor-Arguments.md @@ -1,4 +1,4 @@ -By default, types are created using the 'greediest' public constructor - the one with the most parameters that have [matching](Member-Matching) source members. If there are no available constructors whose parameters can all be matched - and no parameterless constructor - the member for which the type would be created is ignored. +By default, types are created using the 'greediest' public constructor - the one with the most parameters that have [matching](/Member-Matching) source members. If there are no available constructors whose parameters can all be matched - and no parameterless constructor - the member for which the type would be created is ignored. Constructor arguments can be configured by type or name, and constant values or expressions can be specified. @@ -45,6 +45,6 @@ Mapper .ToCtor("customerName")); // To Customer's 'customerName' param ``` -In these examples the `string` `CustomerNum` is parsed and [converted](Type-Conversion) to the `Guid` `customerId` out of the box. +In these examples the `string` `CustomerNum` is parsed and [converted](/Type-Conversion) to the `Guid` `customerId` out of the box. -If configuring constructor parameters is awkward (perhaps because there's a lot of them), you can also [configure an object factory](Configuring-Object-Creation) for a particular object type. \ No newline at end of file +If configuring constructor parameters is awkward (perhaps because there's a lot of them), you can also [configure an object factory](/configuration/Object-Construction) for a particular object type. \ No newline at end of file diff --git a/docs/src/Dependency-Injection.md b/docs/src/configuration/Dependency-Injection.md similarity index 92% rename from docs/src/Dependency-Injection.md rename to docs/src/configuration/Dependency-Injection.md index 2bebee3bd..6c1b823ba 100644 --- a/docs/src/Dependency-Injection.md +++ b/docs/src/configuration/Dependency-Injection.md @@ -58,11 +58,11 @@ Mapper.Before.MappingBegins .Call(ctx => ctx.GetService("PostLogger").Log("Mapping complete")); ``` -To retrieve the originally-configured provider, use `ctx.GetServiceProvider()`. Service providers and services are available in configured [member values](Configuring-Member-Values), [Exception handlers](Configuring-Exception-Handling), [mapping callbacks](Configuring-Mapping-Callbacks) and custom [object factories](Configuring-Object-Construction). +To retrieve the originally-configured provider, use `ctx.GetServiceProvider()`. Service providers and services are available in configured [member values](/configuration/Member-Values), [Exception handlers](/configuration/Exception-Handling), [mapping callbacks](/configuration/Mapping-Callbacks) and custom [object factories](/configuration/Object-Construction). #### During Configuration -To access services in a [MapperConfiguration](Configuration-Classes) instance, use: +To access services in a [MapperConfiguration](/configuration/Classes) instance, use: ```cs public class MyMappingConfiguration : MapperConfiguration diff --git a/docs/src/Dictionary-Mapping-Configuration.md b/docs/src/configuration/Dictionary-Mapping.md similarity index 95% rename from docs/src/Dictionary-Mapping-Configuration.md rename to docs/src/configuration/Dictionary-Mapping.md index 0bfb89736..908b45949 100644 --- a/docs/src/Dictionary-Mapping-Configuration.md +++ b/docs/src/configuration/Dictionary-Mapping.md @@ -136,4 +136,4 @@ Mapper.WhenMapping .Ignore(cd => cd.PhoneNumbers); ``` -Dictionary mapping configuration also supports custom and conditional [object creation](Configuring-Object-Creation), [mapping callbacks](Configuring-Mapping-Callbacks), [target member values](Configuring-Member-Values), etc. \ No newline at end of file +Dictionary mapping configuration also supports custom and conditional [object creation](/configuration/Object-Construction), [mapping callbacks](/configuration/Mapping-Callbacks), [target member values](/configuration/Member-Values), etc. \ No newline at end of file diff --git a/docs/src/Dynamic-Mapping-Configuration.md b/docs/src/configuration/Dynamic-Mapping.md similarity index 96% rename from docs/src/Dynamic-Mapping-Configuration.md rename to docs/src/configuration/Dynamic-Mapping.md index 048eb6146..b896e2e31 100644 --- a/docs/src/Dynamic-Mapping-Configuration.md +++ b/docs/src/configuration/Dynamic-Mapping.md @@ -130,4 +130,4 @@ Mapper.WhenMapping .Ignore(cd => cd.PhoneNumbers); ``` -Dynamic mapping configuration also supports custom and conditional [object creation](Configuring-Object-Creation), [mapping callbacks](Configuring-Mapping-Callbacks), [target member values](Configuring-Member-Values), etc. \ No newline at end of file +Dynamic mapping configuration also supports custom and conditional [object creation](/configuration/Object-Construction), [mapping callbacks](/configuration/Mapping-Callbacks), [target member values](/configuration/Member-Values), etc. \ No newline at end of file diff --git a/docs/src/Configuring-Exception-Handling.md b/docs/src/configuration/Exception-Handling.md similarity index 82% rename from docs/src/Configuring-Exception-Handling.md rename to docs/src/configuration/Exception-Handling.md index d3915e297..34f058137 100644 --- a/docs/src/Configuring-Exception-Handling.md +++ b/docs/src/configuration/Exception-Handling.md @@ -1,4 +1,4 @@ -By default, an `Exception` thrown during a mapping is wrapped in a [`MappingException`](/agileobjects/AgileMapper/blob/master/AgileMapper/MappingException.cs) and rethrown. To configure a mapper to swallow exceptions and return null instead, use: +By default, an `Exception` thrown during a mapping is wrapped in a [`MappingException`](https://github.com/agileobjects/AgileMapper/blob/master/AgileMapper/MappingException.cs) and rethrown. To configure a mapper to swallow exceptions and return null instead, use: ```cs Mapper.WhenMapping diff --git a/docs/src/Ignoring-Target-Members.md b/docs/src/configuration/Ignoring-Target-Members.md similarity index 90% rename from docs/src/Ignoring-Target-Members.md rename to docs/src/configuration/Ignoring-Target-Members.md index 4c26c7574..fab073dd2 100644 --- a/docs/src/Ignoring-Target-Members.md +++ b/docs/src/configuration/Ignoring-Target-Members.md @@ -1,4 +1,4 @@ -Target members which have no [matching](Member-Matching), [compatible](Type-Conversion) source member are ignored by default, but you can also tell a mapper to ignore members which would usually be mapped. For example: +Target members which have no [matching](/Member-Matching), [compatible](/Type-Conversion) source member are ignored by default, but you can also tell a mapper to ignore members which would usually be mapped. For example: ```cs public class OrderDto @@ -22,7 +22,7 @@ Mapper.WhenMapping .Ignore(o => o.Id); // Ignore the Order.Id property ``` -Multiple fields can be ignored with a single configuration, and ignores can be made conditional. Here's an [inline configuration](Inline-Configuration) example: +Multiple fields can be ignored with a single configuration, and ignores can be made conditional. Here's an [inline configuration](/configuration/Inline) example: ```cs // Source, target and mapping types are implicit from the mapping: @@ -116,4 +116,4 @@ Mapper.WhenMapping m.IsPropertyMatching(p => p.IsAssembly)); // Ignore ``` -Again, all ignores can alternatively be configured [inline](Inline-Configuration). \ No newline at end of file +Again, all ignores can alternatively be configured [inline](/configuration/Inline). \ No newline at end of file diff --git a/docs/src/Inline-Configuration.md b/docs/src/configuration/Inline.md similarity index 93% rename from docs/src/Inline-Configuration.md rename to docs/src/configuration/Inline.md index e53f341a1..4fff16c02 100644 --- a/docs/src/Inline-Configuration.md +++ b/docs/src/configuration/Inline.md @@ -6,7 +6,7 @@ var dto = mapper .Map((p, d) => p.Spec).To(d => d.Specification)); ``` -...which also works in [query projections](Query-Projection), for example: +This also works in [query projections](/query-projection), for example: ```cs var dto = await context @@ -46,7 +46,7 @@ var dto = mapper .Map((p, d) => p.Price).To(d => d.Cost)); ``` -Inline configuration can be supplied via the [static](Static-vs-Instance-Mappers) or [instance](Static-vs-Instance-Mappers) APIs. +Inline configuration can be supplied via the [static](/Static-vs-Instance-Mappers) or [instance](/Static-vs-Instance-Mappers) APIs. ### Invalid Configuration diff --git a/docs/src/Configuring-Mapping-Callbacks.md b/docs/src/configuration/Mapping-Callbacks.md similarity index 100% rename from docs/src/Configuring-Mapping-Callbacks.md rename to docs/src/configuration/Mapping-Callbacks.md diff --git a/docs/src/Configuring-Member-Name-Patterns.md b/docs/src/configuration/Member-Name-Patterns.md similarity index 86% rename from docs/src/Configuring-Member-Name-Patterns.md rename to docs/src/configuration/Member-Name-Patterns.md index 1b13ac3e9..00b158ea8 100644 --- a/docs/src/Configuring-Member-Name-Patterns.md +++ b/docs/src/configuration/Member-Name-Patterns.md @@ -1,4 +1,4 @@ -If a naming convention prevents normal [member matching](Member-Matching), you can configure naming patterns to use to match names up. For example: +If a naming convention prevents normal [member matching](/Member-Matching), you can configure naming patterns to use to match names up. For example: ```cs public class ProductDto @@ -36,7 +36,7 @@ Mapper.WhenMapping Configured regex patterns must start with `^` and end with `$`, contain the capturing group `(.+)` to provide the part of a name to use for matching, and have a prefix and / or suffix. -Naming patterns can also be configured [inline](Inline-Configuration) +Naming patterns can also be configured [inline](/configuration/Inline) ```cs var anonSource = new { _PriceValue = default(double) }; diff --git a/docs/src/Configuring-Member-Values.md b/docs/src/configuration/Member-Values.md similarity index 94% rename from docs/src/Configuring-Member-Values.md rename to docs/src/configuration/Member-Values.md index 1ff49e742..68974452f 100644 --- a/docs/src/Configuring-Member-Values.md +++ b/docs/src/configuration/Member-Values.md @@ -16,7 +16,7 @@ Mapper.WhenMapping ``` -**A source expression** (in this example, supplied [inline](Inline-Configuration)): +**A source expression** (in this example, supplied [inline](/configuration/Inline)): ```cs // Source, target and mapping types are implicit from the mapping: @@ -40,7 +40,7 @@ Mapper.WhenMapping .Map("Company ABC", p => p.CompanyName); ``` -**A value from an [injected service](Dependency-Injection)**: +**A value from an [injected service](/configuration/Dependency-Injection)**: ```cs // Retrieve an IDateTimeProvider instance from a configured @@ -52,7 +52,7 @@ Mapper.WhenMapping .To(o => o.DateCreated); // o is the Order ``` -**The result of a function call** ([inline](Inline-Configuration)): +**The result of a function call** ([inline](/configuration/Inline)): ```cs Func companyNameFactory = @@ -77,7 +77,7 @@ Mapper.WhenMapping .To(p => p.CompanyName); // p is the Product ``` -And in an [inline](Inline-Configuration) example: +And in an [inline](/configuration/Inline) example: ```cs Mapper.Map(productDto).ToANew(cfg => cfg diff --git a/docs/src/Null-Results.md b/docs/src/configuration/Null-Results.md similarity index 82% rename from docs/src/Null-Results.md rename to docs/src/configuration/Null-Results.md index 1d2abcdc7..7687d4555 100644 --- a/docs/src/Null-Results.md +++ b/docs/src/configuration/Null-Results.md @@ -1,4 +1,4 @@ -If a target complex type member has no [matching source member](Member-Matching), no matched [constructor arguments](Object-Construction), and none of its child members have matching source members, it will be mapped to null. +If a target complex type member has no [matching source member](/Member-Matching), no matched [constructor arguments](/Object-Construction), and none of its child members have matching source members, it will be mapped to null. For example: diff --git a/docs/src/Configuring-Object-Construction.md b/docs/src/configuration/Object-Construction.md similarity index 91% rename from docs/src/Configuring-Object-Construction.md rename to docs/src/configuration/Object-Construction.md index 1566ff5d6..1856806da 100644 --- a/docs/src/Configuring-Object-Construction.md +++ b/docs/src/configuration/Object-Construction.md @@ -21,7 +21,7 @@ Mapper.WhenMapping }); ``` -Configure a conditional custom factory using ([inline](Inline-Configuration) example): +Configure a conditional custom factory using ([inline](/configuration/Inline) example): ```cs Mapper.Map(customerViewModels).ToANew(cfg => cfg diff --git a/docs/src/configuration/Object-Identifiers.md b/docs/src/configuration/Object-Identifiers.md new file mode 100644 index 000000000..d49cfeb67 --- /dev/null +++ b/docs/src/configuration/Object-Identifiers.md @@ -0,0 +1,23 @@ +Objects are identified during collection [updates](/Performing-Updates) and [merges](/Performing-Merges) using members with the following names: + +* `Id` +* `Id` +* `Identifier` +* `Identifier` + +You can configure an object to be uniquely identified with a different member using: + +```cs +Mapper.WhenMapping + .InstancesOf() // Apply to NamedCustomer mappings + .IdentifyUsing(c => c.Name); // Identify using NamedCustomer.Name +``` + +Or, configured [inline](/configuration/Inline): + +```cs +Mapper.Map(customerDtos).ToANew(cfg => cfg + .WhenMapping + .InstancesOf() + .IdentifyUsing(c => c.Name)); // Identify using NamedCustomer.Name +``` \ No newline at end of file diff --git a/docs/src/Pairing-Derived-Types.md b/docs/src/configuration/Pairing-Derived-Types.md similarity index 79% rename from docs/src/Pairing-Derived-Types.md rename to docs/src/configuration/Pairing-Derived-Types.md index d464f581a..7d598d1dd 100644 --- a/docs/src/Pairing-Derived-Types.md +++ b/docs/src/configuration/Pairing-Derived-Types.md @@ -1,4 +1,4 @@ -Derived type pairing matches particular derived sources types to particular derived target types. Most of the time [this is done automatically](Derived-Types), but if your derived types aren't consistently-named, or you want to make derived type mapping conditional, you can configure it. +Derived type pairing matches particular derived sources types to particular derived target types. Most of the time [this is done automatically](/Derived-Types), but if your derived types aren't consistently-named, or you want to make derived type mapping conditional, you can configure it. For example: @@ -31,7 +31,7 @@ var animals = Mapper.Map(animalViewModels).ToANew>(); // animals[1] is of type Dog ``` -...and can be applied conditionally ([inline](Inline-Configuration) example): +...and can be applied conditionally ([inline](/configuration/Inline) example): ```cs Mapper @@ -43,4 +43,4 @@ Mapper .MapTo()); // Create an instance of Dog ``` -Conditional derived type mappings can also be configured [for Dictionaries](Dictionary-Mapping#conditional-derived-types). \ No newline at end of file +Conditional derived type mappings can also be configured [for Dictionaries](/configuration/Dictionary-Mapping#conditional-derived-types). \ No newline at end of file diff --git a/docs/src/To-String-Formatting.md b/docs/src/configuration/To-String-Formatting.md similarity index 100% rename from docs/src/To-String-Formatting.md rename to docs/src/configuration/To-String-Formatting.md diff --git a/docs/src/configuration/index.md b/docs/src/configuration/index.md new file mode 100644 index 000000000..8a1c495ef --- /dev/null +++ b/docs/src/configuration/index.md @@ -0,0 +1,14 @@ +Many aspects of mapping can be configured, but no up-front type registration is required - a mapping function is created and cached the first time two types are mapped. + +Various configuration options are available: + +- [Static](/Static-vs-Instance-Mappers) configuration (`Mapper.WhenMapping`) configures a default, instance-scoped mapper behind the scenes. This configures the mapper used when you call `Mapper.Map(source)` + +- [Instance](/Static-vs-Instance-Mappers) configuration (`mapper.WhenMapping`) configures that particular instance + +- [Inline](/configuration/Inline) configuration combines the configuration of the mapper performing the mapping with the inline configuration you supply + +- [Class](/configuration/Classes) configuration splits configuration up into dedicated configuration classes. + +The same API is available in all four contexts. + diff --git a/docs/src/css/styles.css b/docs/src/css/styles.css new file mode 100644 index 000000000..d6f1e0a5e --- /dev/null +++ b/docs/src/css/styles.css @@ -0,0 +1,54 @@ +body { + font: 400 11pt 'Segoe UI', Calibri, Arial, sans-serif !important; +} + +h1, h2, h3, h4, input[type=submit] { + font-family: 'Segoe UI Light', Calibri, Arial, sans-serif !important; + margin: 0 0 .5em; +} + +h1 { + font-size: 2.5em; +} + +h2 { + font-size: 2em; +} + +h3 { + font-size: 1.6em; +} + +h4 { + font-size: 1.2em; + margin-left: .7em; +} + +p code, li code { + border: none; + padding: 2px 0; + font-size: 11pt; + color: black; +} + +pre code { + font-size: 11pt; +} + +span.caption-text { + color: #dcdcdc; + background: #1e1e1e; +} + +p a code { + text-decoration: underline; +} + +.wy-menu-vertical li.current a { + color: #1e1e1e; +} + +li.current { + border-top: 1px solid #010101; + border-bottom: 1px solid #010101; +} diff --git a/docs/src/index.md b/docs/src/index.md index bd2583691..e96190619 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,10 +1,10 @@ ## Overview -AgileMapper is a zero-configuration, [highly-configurable](Configuration) object-object mapper with [viewable execution plans](Using-Execution-Plans), targetting [.NET Standard 1.0+](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) and .NET 3.5+. It performs [query projections](Query-Projection), object creation, deep clones, id-aware [updates](Performing-Updates) and [merges](Performing-Merges), and can be used via [extension methods](Mapping-Extension-Methods), or a [static or instance](Static-vs-Instance-Mappers) API. +AgileMapper is a zero-configuration, [highly-configurable](/configuration) object-object mapper with [viewable execution plans](/Using-Execution-Plans), targetting [.NET Standard 1.0+](https://docs.microsoft.com/en-us/dotnet/articles/standard/library) and .NET 3.5+. It performs [query projections](/query-projection), object creation, deep clones, id-aware [updates](/Performing-Updates) and [merges](/Performing-Merges), and can be used via [extension methods](/Mapping-Extension-Methods), or a [static or instance](/Static-vs-Instance-Mappers) API. -Mapping functions are created and cached the first time two types are mapped - no up-front configuration is necessary. You can [cache up-front](Using-Execution-Plans) if you prefer, though. +Mapping functions are created and cached the first time two types are mapped - no up-front configuration is necessary. You can [cache up-front](/Using-Execution-Plans) if you prefer, though. -[Available via NuGet](https://www.nuget.org/packages/AgileObjects.AgileMapper) and licensed with the [MIT licence](/agileobjects/AgileMapper/blob/master/LICENCE.md), you can install it via the [package manager console](https://docs.nuget.org/consume/package-manager-console): +[Available via NuGet](https://www.nuget.org/packages/AgileObjects.AgileMapper) and licensed with the [MIT licence](https://github.com/agileobjects/AgileMapper/blob/master/LICENCE.md), you can install it via the [package manager console](https://docs.nuget.org/consume/package-manager-console): PM> Install-Package AgileObjects.AgileMapper @@ -24,7 +24,7 @@ var customer = customerViewModel.Map().ToANew(); ### Query Projection -[Project](Query-Projection) entities to another Type using: +[Project](/query-projection) entities to another Type using: ```cs var customerVm = await dbContext @@ -45,7 +45,7 @@ var clonedCustomer = customerToBeCloned.DeepClone(); ### Updating -[Update](Performing-Updates) an object's members with values from another using: +[Update](/Performing-Updates) an object's members with values from another using: ```cs Mapper.Map(customerSaveRequest).Over(customer); @@ -55,7 +55,7 @@ customerSaveRequest.Map().Over(customer); ### Merging -[Merge](Performing-Merges) an object's unpopulated members with values from another using: +[Merge](/Performing-Merges) an object's unpopulated members with values from another using: ```cs Mapper.Map(customerDto).OnTo(customer); @@ -65,7 +65,7 @@ customerDto.Map().OnTo(customer); ## View a Mapping Execution Plan -View an [execution plan](Using-Execution-Plans) to see how two object types will be mapped; this also caches the plan, so you can use it to choose when to incur that cost. Use: +View an [execution plan](/Using-Execution-Plans) to see how two object types will be mapped; this also caches the plan, so you can use it to choose when to incur that cost. Use: ```cs // For object creation: diff --git a/docs/src/Query-Projection-Configuration.md b/docs/src/query-projection/Configuration.md similarity index 62% rename from docs/src/Query-Projection-Configuration.md rename to docs/src/query-projection/Configuration.md index 429eb5494..c44858844 100644 --- a/docs/src/Query-Projection-Configuration.md +++ b/docs/src/query-projection/Configuration.md @@ -1,4 +1,4 @@ -[Query projection](Query-Projection) supports a subset of regular mapping [configuration](Configuration). Anything [applicable](#limitations) configured using a `Mapper.WhenMapping` API - [static](Static-vs-Instance-Mappers) or instance - will also be applied to query projections. +[Query projection](/query-projection) supports a subset of regular mapping [configuration](/configuration). Anything [applicable](#limitations) configured using a `Mapper.WhenMapping` API - [static](/Static-vs-Instance-Mappers) or instance - will also be applied to query projections. ### Static API @@ -20,7 +20,7 @@ var productDtos = await context .ToArrayAsync(); ``` -In this case, the `Product.Spec` -> `ProductDto.Specification` custom [member value](Configuring-Member-Values) will be used in the projection because both the configuration and projection are performed using the default mapper. +In this case, the `Product.Spec` -> `ProductDto.Specification` custom [member value](/configuration/Member-Values) will be used in the projection because both the configuration and projection are performed using the default mapper. ### Instance API @@ -54,22 +54,22 @@ var productDtos = await context Because projections are performed by [IQueryProvider](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider)s, only the following configuration options are applied: -- Custom [member values](Configuring-Member-Values), as above +- Custom [member values](/configuration/Member-Values), as above -- Custom [constructor arguments](Configuring-Constructor-Arguments) +- Custom [constructor arguments](/configuration/Constructor-Arguments) -- Custom [naming patterns](Configuring-Member-Name-Patterns) +- Custom [naming patterns](/configuration/Member-Name-Patterns) -- To-String [formatting](To-String-Formatting) +- To-String [formatting](/configuration/To-String-Formatting) -- Enum [pairing](Enum-Mapping#configuring-enum-pairs) +- Enum [pairing](/configuration/Enum-Mapping#configuring-enum-pairs) -- [Ignored](Ignoring-Target-Members) members +- [Ignored](/configuration/Ignoring-Target-Members) members -- Object [factories](Configuring-Object-Construction) +- Object [factories](/configuration/Object-Construction) -- Null [mapping results](Null-Results) +- Null [mapping results](/configuration/Null-Results) -Most notably, [callbacks](Configuring-Mapping-Callbacks), [object tracking](Mapped-Object-Tracking) and [derived type pairing](Pairing-Derived-Types) are not supported - although you can [project to derived types](Projecting-to-Derived-Types) conditionally. +Most notably, [callbacks](/configuration/Mapping-Callbacks), [object tracking](/configuration/Mapped-Object-Tracking) and [derived type pairing](/configuration/Pairing-Derived-Types) are not supported - although you can [project to derived types](/query-projection/Derived-Types) conditionally. In every case, it is up to you to configure values your IQueryProvider can support - configured values which will definitely be unsupported - like function invocations - are automatically filtered out of query projections. \ No newline at end of file diff --git a/docs/src/Projecting-to-Derived-Types.md b/docs/src/query-projection/Derived-Types.md similarity index 76% rename from docs/src/Projecting-to-Derived-Types.md rename to docs/src/query-projection/Derived-Types.md index 790a8aef4..3b7e3253f 100644 --- a/docs/src/Projecting-to-Derived-Types.md +++ b/docs/src/query-projection/Derived-Types.md @@ -1,4 +1,4 @@ -If your [`IQueryProvider`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider) [supports](Entity-Framework#derived-types) casting projected instances to a base Type, you can project to derived Types via configured conditions. For example: +If your [`IQueryProvider`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider) [supports](/query-projection/Entity-Framework#derived-types) casting projected instances to a base Type, you can project to derived Types via configured conditions. For example: ```cs // Using an EF Core DbContext: diff --git a/docs/src/Entity-Framework.md b/docs/src/query-projection/Entity-Framework.md similarity index 96% rename from docs/src/Entity-Framework.md rename to docs/src/query-projection/Entity-Framework.md index 09b219bc6..5bf90ca9c 100644 --- a/docs/src/Entity-Framework.md +++ b/docs/src/query-projection/Entity-Framework.md @@ -1,4 +1,4 @@ -AgileMapper contains version-specific support for Entity Framework 5, [Entity Framework 6](https://docs.microsoft.com/en-us/ef/ef6), and [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core), extending each version's ability to support [query projection](Query-Projection). +AgileMapper contains version-specific support for Entity Framework 5, [Entity Framework 6](https://docs.microsoft.com/en-us/ef/ef6), and [Entity Framework Core](https://docs.microsoft.com/en-us/ef/core), extending each version's ability to support [query projection](/query-projection). ### Type Conversion @@ -34,8 +34,8 @@ The following conversions are supported, along with the same projections from an | Recursion ** |
  • - [x]
| | | | Collection Members *** |
  • - [x]
|
  • - [x]
| | -\* EF5 and EF6 do not support casting a projected Type to its base Type, so do not support projecting to [conditional derived types](Projecting-to-Derived-Types). +\* EF5 and EF6 do not support casting a projected Type to its base Type, so do not support projecting to [conditional derived types](/query-projection/Derived-Types). -\** EF5 and EF6 do not support creating instances of a projected Type with [differing numbers](https://stackoverflow.com/questions/39139402/the-type-appears-in-two-structurally-incompatible-initializations-within-a-singl) of member initialisations in the same query, so do not support projecting [recursive relationships](Projecting-Recursive-Relationships). +\** EF5 and EF6 do not support creating instances of a projected Type with [differing numbers](https://stackoverflow.com/questions/39139402/the-type-appears-in-two-structurally-incompatible-initializations-within-a-singl) of member initialisations in the same query, so do not support projecting [recursive relationships](/query-projection/Recursive-Relationships). \*** EF5 can only project to `IEnumerable{T}` members, not `ICollection{T}`, `List{T}`, `T[]`, etc. \ No newline at end of file diff --git a/docs/src/Join-Entities.md b/docs/src/query-projection/Join-Entities.md similarity index 100% rename from docs/src/Join-Entities.md rename to docs/src/query-projection/Join-Entities.md diff --git a/docs/src/Projecting-Recursive-Relationships.md b/docs/src/query-projection/Recursive-Relationships.md similarity index 84% rename from docs/src/Projecting-Recursive-Relationships.md rename to docs/src/query-projection/Recursive-Relationships.md index 17d284320..4de783dd9 100644 --- a/docs/src/Projecting-Recursive-Relationships.md +++ b/docs/src/query-projection/Recursive-Relationships.md @@ -1,4 +1,4 @@ -If your [`IQueryProvider`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider) [supports](Entity-Framework#recursion) it, you can project recursive relationships to a specified depth. For example, with these classes: +If your [`IQueryProvider`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider) [supports](/query-projection/Entity-Framework#recursion) it, you can project recursive relationships to a specified depth. For example, with these classes: ```cs // Entity: @@ -97,4 +97,4 @@ var stringsDto = await context ...and so on. -Note that it is not possible to use [object tracking](Mapped-Object-Tracking) in query projections, so [identity integrity](Mapped-Object-Tracking#identity-integrity) is not maintained. \ No newline at end of file +Note that it is not possible to use [object tracking](/configuration/Mapped-Object-Tracking) in query projections, so [identity integrity](/configuration/Mapped-Object-Tracking#identity-integrity) is not maintained. \ No newline at end of file diff --git a/docs/src/Query-Projection.md b/docs/src/query-projection/index.md similarity index 64% rename from docs/src/Query-Projection.md rename to docs/src/query-projection/index.md index 43a09b7e2..1774c2dd5 100644 --- a/docs/src/Query-Projection.md +++ b/docs/src/query-projection/index.md @@ -1,6 +1,6 @@ AgileMapper can project an `IQueryable{T}` to any other type supported by the [`IQueryProvider`](https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryprovider), which can increase performance by only selecting the required data from an underlying data store, and decrease lines of code by directly materializing a DTO or view model, instead of materializing then mapping entities. -Query projection supports a subset of regular mapping [configuration](Query-Projection-Configuration), and can be configured [inline](Inline-Configuration). It also supports projection of recursive relationships to a specified depth. +Query projection supports a subset of regular mapping [configuration](/query-projection/Configuration), and can be configured [inline](/configuration/Inline). It also supports projection of recursive relationships to a specified depth. To project a query, use: @@ -12,7 +12,7 @@ var orderDtos = await context .ToListAsync(); ``` -`.Project()` uses the default mapper - the one used behind the scenes by the [static](Static-vs-Instance-Mappers) `Mapper` API. To project a query using an instance-scoped mapper, use: +`.Project()` uses the default mapper - the one used behind the scenes by the [static](/Static-vs-Instance-Mappers) `Mapper` API. To project a query using an instance-scoped mapper, use: ```cs var orderDtos = await context @@ -23,7 +23,7 @@ var orderDtos = await context ### Viewing Projection Plans -The [plan](Using-Execution-Plans) for a query projection can be viewed and cached just like those for regular mappings, but because they're cached against the IQueryProvider's Type, an instance of the queryable being projected is required. +The [plan](/Using-Execution-Plans) for a query projection can be viewed and cached just like those for regular mappings, but because they're cached against the IQueryProvider's Type, an instance of the queryable being projected is required. For example: diff --git a/mkdocs.yml b/mkdocs.yml index 2c479c1f5..aa3ad4542 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,58 +1,62 @@ site_name: AgileMapper -repo_url: https://github.com/agileobjects/AgileMapper site_description: 'AgileMapper: A zero-configuration, highly-configurable object-object mapper with viewable execution plans. Projects queries, transforms, deep clones, updates and merges via extension methods, or a static or instance API. Targets .NET Standard 1.0+ and .NET 3.5+' site_author: Steve Wilkes +repo_url: https://github.com/agileobjects/AgileMapper + docs_dir: 'docs/src' site_dir: 'docs/site' + extra_css: - https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/vs2015.min.css + - css/styles.css + nav: - - Home: index.md - - Member matching: Member-Matching.md - - Object construction: Object-Construction.md - - Type conversion: Type-Conversion.md - - Collections: Collections.md - - Entity mapping: Entity-Mapping.md - - Dictionary mapping: Dictionary-Mapping.md - - Dynamic mapping: Dynamic-Mapping.md - - Meta members: Meta-Members.md - - Enum mapping: Enum-Mapping.md + - General Use: + - Member matching: Member-Matching.md + - Object construction: Object-Construction.md + - Type conversion: Type-Conversion.md + - Collections: Collections.md + - Entity mapping: Entity-Mapping.md + - Dictionary mapping: Dictionary-Mapping.md + - Dynamic mapping: Dynamic-Mapping.md + - Meta members: Meta-Members.md + - Enum mapping: Enum-Mapping.md + - Object updating: Performing-Updates.md + - Object merging: Performing-Merges.md + - Object flattening: Object-Flattening.md + - Object unflattening: Object-Unflattening.md + - Using execution plans: Using-Execution-Plans.md + - Derived types: Derived-Types.md + - Object tracking: Mapped-Object-Tracking.md + - Static vs Instance API: Static-vs-Instance-Mappers.md + - Mapping extension methods: Mapping-Extension-Methods.md + - Mapping validation: Validating-Mappings.md - Query Projection: - - Overview: Query-Projection.md - - Configuration: Query-Projection-Configuration.md - - Derived Types: Projecting-to-Derived-Types.md - - Recursion: Projecting-Recursive-Relationships.md - - Join entities: Join-Entities.md - - Entity Framework: Entity-Framework.md - - Object updating: Performing-Updates.md - - Object merging: Performing-Merges.md - - Object flattening: Object-Flattening.md - - Object unflattening: Object-Unflattening.md - - Using execution plans: Using-Execution-Plans.md - - Derived types: Derived-Types.md - - Object tracking: Mapped-Object-Tracking.md - - Static vs Instance API: Static-vs-Instance-Mappers.md - - Mapping extension methods: Mapping-Extension-Methods.md - - Mapping validation: Validating-Mappings.md + - Overview: query-projection/index.md + - Configuration: query-projection/Configuration.md + - Derived Types: query-projection/Derived-Types.md + - Recursion: query-projection/Recursive-Relationships.md + - Join entities: query-projection/Join-Entities.md + - Entity Framework: query-projection/Entity-Framework.md - Configuration: - - Overview: Configuration.md - - Configuring inline: Inline-Configuration.md - - Configuration classes: Configuration-Classes.md - - Dependency injection: Dependency-Injection.md - - Member values: Configuring-Member-Values.md - - Constructor arguments: Configuring-Constructor-Arguments.md - - Member name patterns: Configuring-Member-Name-Patterns.md - - To-string formatting: To-String-Formatting.md + - Overview: configuration/index.md + - Configuring inline: configuration/Inline.md + - Configuration classes: configuration/Classes.md + - Dependency injection: configuration/Dependency-Injection.md + - Member values: configuration/Member-Values.md + - Constructor arguments: configuration/Constructor-Arguments.md + - Member name patterns: configuration/Member-Name-Patterns.md + - To-string formatting: configuration/To-String-Formatting.md - Enum pairing: Enum-Mapping/#configuring-enum-pairs - - Dictionaries: Dictionary-Mapping-Configuration.md - - Dynamics: Dynamic-Mapping-Configuration.md - - Ignoring members: Ignoring-Target-Members.md - - Object identifiers: Configuring-Object-Identifiers.md - - Object construction: Configuring-Object-Construction.md - - Null results: Null-Results.md - - Derived type pairing: Pairing-Derived-Types.md - - Cloning Mappers: Cloning-Mappers.md - - Assembly scanning: Assembly-Scanning.md - - Exception handling: Configuring-Exception-Handling.md - - Mapping callbacks: Configuring-Mapping-Callbacks.md + - Dictionaries: configuration/Dictionary-Mapping.md + - Dynamics: configuration/Dynamic-Mapping.md + - Ignoring members: configuration/Ignoring-Target-Members.md + - Object identifiers: configuration/Object-Identifiers.md + - Object construction: configuration/Object-Construction.md + - Null results: configuration/Null-Results.md + - Derived type pairing: configuration/Pairing-Derived-Types.md + - Cloning Mappers: configuration/Cloning-Mappers.md + - Assembly scanning: configuration/Assembly-Scanning.md + - Exception handling: configuration/Exception-Handling.md + - Mapping callbacks: configuration/Mapping-Callbacks.md theme: readthedocs \ No newline at end of file