-
-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
UnsafeMemberAccessor
for private property and fields
- Loading branch information
1 parent
0f61698
commit e925792
Showing
80 changed files
with
1,876 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
--- | ||
sidebar_position: 13 | ||
sidebar_position: 14 | ||
description: A list of conversions supported by Mapperly | ||
--- | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
--- | ||
sidebar_position: 12 | ||
description: Private member mapping | ||
--- | ||
|
||
# Private member mapping | ||
|
||
As of .NET 8.0, Mapperly supports mapping members that are normally inaccessible like `private` or `protected` properties. This is made possible by using the [UnsafeAccessorAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unsafeaccessorattribute) which lets Mapperly access normally inaccessible members with zero overhead while being completely AOT safe. | ||
|
||
By default `IncludedMembers` is set to `MemberVisibility.AllAccessible` which will configure Mapperly to map members of all accessibility levels as long as they are ordinarily accessible. To enable unsafe accessor usage, set `IncludedMembers` to `MemberVisibility.All`. Mapperly will then try to map members of all accessibilities, including ones that are not usually visible to external types. | ||
|
||
```csharp | ||
public class Fruit | ||
{ | ||
private bool _isSeeded; | ||
|
||
public string Name { get; set; } | ||
|
||
private int Sweetness { get; set; } | ||
} | ||
|
||
// highlight-start | ||
[Mapper(IncludedMembers = MemberVisibility.All)] | ||
// highlight-end | ||
public partial class FruitMapper | ||
{ | ||
public partial FruitDto ToDto(Fruit fruit); | ||
} | ||
``` | ||
|
||
## Generated code | ||
|
||
```csharp | ||
public partial class FruitMapper | ||
{ | ||
private partial global::FruitDto ToDto(global::Fruit source) | ||
{ | ||
var target = new global::FruitDto(); | ||
target.GetIsSeeded1() = source.GetIsSeeded(); | ||
target.Name = source.Name; | ||
target.SetSweetness(source.GetSweetness()); | ||
return target; | ||
} | ||
} | ||
|
||
static file class UnsafeAccessor | ||
{ | ||
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "_isSeeded")] | ||
public static extern ref bool GetSeeded(this global::Fruit target); | ||
|
||
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "_isSeeded")] | ||
public static extern ref bool GetSeeded1(this global::FruitDto target); | ||
|
||
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "get_Sweetness")] | ||
public static extern int GetSweetness(this global::Fruit source); | ||
|
||
[global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "set_Sweetness")] | ||
public static extern void SetSweetness(this global::FruitDto target, int value); | ||
} | ||
``` | ||
|
||
Here Mapperly generates a file scoped class containing extension method for each internal member for both the source and target. Mapperly then uses the extension methods to get and set the members. Note that this uses zero reflection and is as performant as using an ordinary property or field. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
namespace Riok.Mapperly.Abstractions; | ||
|
||
/// <summary> | ||
/// Determines what member accessibility Mapperly will attempt to map. | ||
/// </summary> | ||
[Flags] | ||
public enum MemberVisibility | ||
{ | ||
/// <summary> | ||
/// Maps all accessible members. | ||
/// </summary> | ||
AllAccessible = All | Accessible, | ||
|
||
/// <summary> | ||
/// Maps all members, even members which are not directly accessible by the mapper are mapped | ||
/// by using accessors with the UnsafeAccessorAttribute. This can only be used for .NET 8.0 and later. | ||
/// </summary> | ||
All = Public | Internal | Protected | Private, | ||
|
||
/// <summary> | ||
/// Maps only accessible members. | ||
/// If not set, the UnsafeAccessorAttribute is used to generate mappings for inaccessible members. | ||
/// </summary> | ||
Accessible = 1 << 0, | ||
|
||
/// <summary> | ||
/// Maps public members. | ||
/// </summary> | ||
Public = 1 << 1, | ||
|
||
/// <summary> | ||
/// Maps internal members. | ||
/// </summary> | ||
Internal = 1 << 2, | ||
|
||
/// <summary> | ||
/// Maps protected members. | ||
/// </summary> | ||
Protected = 1 << 3, | ||
|
||
/// <summary> | ||
/// Maps private members. | ||
/// </summary> | ||
Private = 1 << 4, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.