Skip to content

Commit

Permalink
Merge pull request MapsterMapper#32 from chaowlert/mef
Browse files Browse the repository at this point in the history
Add easier support for 3rd party service locators
  • Loading branch information
eswann committed Jan 25, 2016
2 parents f2c9690 + 6aaaab8 commit 8a856cd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ You make the object, Mapster maps to the object.

TDestination destObject = new TDestination();
destObject = TypeAdapter.Adapt(sourceObject, destObject);

or using extension methods

TDestination destObject = new TDestination();
Expand Down Expand Up @@ -206,7 +206,7 @@ As an alternative to `NewConfig`, you can use `ForType` in the same way:
.Map(dest => dest.FullName,
src => string.Format("{0} {1}", src.FirstName, src.LastName));

`ForType` differs in that it will create a new mapping if one doesn't exist, but if the specified TSource => TDestination
`ForType` differs in that it will create a new mapping if one doesn't exist, but if the specified TSource => TDestination
mapping does already exist, it will enhance the existing mapping instead of dropping and replacing it.

#####Global Settings <a name="SettingsGlobal"></a>
Expand Down Expand Up @@ -245,7 +245,7 @@ Finally, Mapster also provides methods to inherit explicitly.
.Inherits<SimplePoco, SimpleDto>();

#####Rule based settings <a name="SettingsRuleBased"></a>
To set the setting at a more granular level. You can use the `When` method in global settings.
To set the setting at a more granular level. You can use the `When` method in global settings.
In the example below, when any source type and destination type are the same, we will not the copy the `Id` property.

TypeAdapterConfig.GlobalSettings.When((srcType, destType, mapType) => srcType == destType)
Expand All @@ -257,7 +257,7 @@ In this example, the config would only apply to Query Expressions (projections).
.IgnoreAttribute(typeof(NotMapAttribute));

#####Overload settings <a name="SettingsOverload"></a>
You may wish to have different settings in different scenarios.
You may wish to have different settings in different scenarios.
If you would not like to apply setting at a static level, Mapster also provides setting instance configurations.

var config = new TypeAdapterConfig();
Expand Down Expand Up @@ -285,17 +285,17 @@ Or to an Adapter instance.

#####Assembly scanning <a name="AssemblyScanning"></a>
It's relatively common to have mapping configurations spread across a number of different assemblies.
Perhaps your domain assembly has some rules to map to domain objects and your web api has some specific rules to map to your
api contracts. In these cases, it can be helpful to allow assemblies to be scanned for these rules so you have some basic
method of organizing your rules and not forgetting to have the registration code called. In some cases, it may even be necessary to
Perhaps your domain assembly has some rules to map to domain objects and your web api has some specific rules to map to your
api contracts. In these cases, it can be helpful to allow assemblies to be scanned for these rules so you have some basic
method of organizing your rules and not forgetting to have the registration code called. In some cases, it may even be necessary to
register the assemblies in a particular order, so that some rules override others. Assembly scanning helps with this.
Assembly scanning is simple, just create any number of IRegister implementations in your assembly, then call `Scan` from your TypeAdapterConfig class:

public class MyRegister : IRegister
{
public void Register(TypeAdapterConfig config){
config.NewConfig<TSource, TDestination>();

//OR to create or enhance an existing configuration

config.ForType<TSource, TDestination>();
Expand All @@ -304,13 +304,18 @@ Assembly scanning is simple, just create any number of IRegister implementations

To scan and register at the Global level:

TypeAdapterConfig.Global.Scan(assembly1, assembly2, assemblyN)
TypeAdapterConfig.GlobalSettings.Scan(assembly1, assembly2, assemblyN)

For a specific config instance:

var config = new TypeAdapterConfig();
config.Scan(assembly1, assembly2, assemblyN);

If you use other assembly scanning library such as MEF, you can easily apply registration with `Apply` method.

var registers = container.GetExports<IRegister>();
config.Apply(registers);

####Basic Customization <a name="Basic"></a>
When the default convention mappings aren't enough to do the job, you can specify complex source mappings.

Expand Down Expand Up @@ -350,7 +355,7 @@ In Mapster 2.0, you can even map when source and destination property types are
src => src.GenderString); //"Male" or "Female"

#####Merge object <a name="Merge"></a>
By default, Mapster will map all properties, even source properties containing null values.
By default, Mapster will map all properties, even source properties containing null values.
You can copy only properties that have values by using `IgnoreNullValues` method.

TypeAdapterConfig<TSource, TDestination>
Expand All @@ -365,8 +370,8 @@ By default, Mapster will recursively map nested objects. You can do shallow copy
.ShallowCopyForSameType(true);

#####Preserve reference (preventing circular reference stackoverflow) <a name="PreserveReference"></a>
When mapping objects with circular references, a stackoverflow exception will result.
This is because Mapster will get stuck in a loop tring to recursively map the circular reference.
When mapping objects with circular references, a stackoverflow exception will result.
This is because Mapster will get stuck in a loop tring to recursively map the circular reference.
If you would like to map circular references or preserve references (such as 2 properties pointing to the same object), you can do it by setting `PreserveReference` to `true`

TypeAdapterConfig<TSource, TDestination>
Expand Down
22 changes: 16 additions & 6 deletions src/Mapster/TypeAdapterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,24 @@ public IList<IRegister> Scan(params Assembly[] assemblies)
.SelectMany(registerTypes =>
registerTypes.Select(registerType => (IRegister)Activator.CreateInstance(registerType))).ToList();

foreach (IRegister register in registers)
{
register.Register(this);
}
return registers;
this.Apply(registers);
return registers;
}

internal void Clear()
public void Apply(IEnumerable<Lazy<IRegister>> registers)
{
this.Apply(registers.Select(register => register.Value));
}

public void Apply(IEnumerable<IRegister> registers)
{
foreach (IRegister register in registers)
{
register.Register(this);
}
}

internal void Clear()
{
var keys = Dict.Keys.ToList();
foreach (var key in keys)
Expand Down

0 comments on commit 8a856cd

Please sign in to comment.