Skip to content

Commit 41a7548

Browse files
committed
Create README.md
1 parent 2d66532 commit 41a7548

File tree

1 file changed

+268
-0
lines changed

1 file changed

+268
-0
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
# ValueMapper
2+
3+
A high-performance, lightweight object-to-object mapper for .NET with zero dependencies. ValueMapper provides fast mapping capabilities with a simple API, making it easy to map between different object types while maintaining good performance.
4+
5+
## Feature Comparison
6+
7+
| Feature | ValueMapper | Mapster | AutoMapper |
8+
| ---------------------------- | ------------------- | ------------- | -------------- |
9+
| Zero Dependencies ||||
10+
| Basic Property Mapping ||||
11+
| Flattening ||||
12+
| Deep Object Mapping ||||
13+
| Collection Mapping ||||
14+
| Enum Mapping ||||
15+
| Custom Property Mapping | ✅ (attr) |||
16+
| Property Ignoring ||||
17+
| Type Conversion ||||
18+
| Nullable Handling ||||
19+
| Configuration API ||||
20+
| Custom Value Resolvers ||||
21+
| Conditional Mapping ||||
22+
| Circular Reference Handling ||||
23+
| Before/After Mapping Actions ||||
24+
| Runtime Configuration ||||
25+
| Mapping Validation ||||
26+
| Collection Type Conversion | ❌ (List→List only) |||
27+
| Parallel Collection Mapping | ✅ (built-in) | ❌+ | ❌+ |
28+
| Compile-time Type Safety || ❌‡ | ❌‡ |
29+
| Mapping Cache ||||
30+
| Performance (vs Manual)\* | ~11.95x slower | ~8.11x slower | ~12.67x slower |
31+
32+
\* Based on benchmark results for single object mapping. For collection mapping (100,000 items), ValueMapper performs better: ValueMapper (39.84ms), Mapster (65.34ms), AutoMapper (70.80ms).
33+
34+
- Can be implemented manually
35+
36+
## Features
37+
38+
- ✨ Zero dependencies
39+
- 🚀 High performance
40+
- 💡 Simple API
41+
- 🔄 Automatic type conversion
42+
- 🏷️ Custom property mapping via attributes
43+
- ⏭️ Property ignoring
44+
- 📝 Collection mapping
45+
- 🔄 Enum mapping (case-insensitive)
46+
- 🧵 Parallel collection mapping for large datasets
47+
- 🔒 Thread-safe operation
48+
- 🔥 Mapping compilation caching
49+
50+
## Installation
51+
52+
```shell
53+
dotnet add package ValueMapper
54+
```
55+
56+
## Usage Examples
57+
58+
### Basic Property Mapping
59+
60+
```csharp
61+
var source = new Source
62+
{
63+
Name = "John Doe",
64+
Age = 30,
65+
City = "New York"
66+
};
67+
68+
var destination = ValueMapper.Map<Source, Destination>(source);
69+
```
70+
71+
### Custom Property Mapping Using Attributes
72+
73+
```csharp
74+
public class Source
75+
{
76+
[ValueMapperMapping("CustomName")]
77+
public string SourceProperty { get; set; }
78+
}
79+
80+
public class Destination
81+
{
82+
public string CustomName { get; set; }
83+
}
84+
85+
var source = new Source { SourceProperty = "Custom Value" };
86+
var destination = ValueMapper.Map<Source, Destination>(source);
87+
// destination.CustomName will contain "Custom Value"
88+
```
89+
90+
### Ignoring Properties
91+
92+
```csharp
93+
public class Source
94+
{
95+
public string Name { get; set; }
96+
[ValueMapperIgnore]
97+
public string IgnoredProperty { get; set; }
98+
}
99+
100+
// Or ignore properties at runtime
101+
var ignoredProperties = new HashSet<string> { "Age" };
102+
var destination = ValueMapper.Map<Source, Destination>(source, ignoredProperties);
103+
```
104+
105+
### Collection Mapping
106+
107+
```csharp
108+
var sourceList = new List<Source>
109+
{
110+
new Source { Name = "John", Age = 30 },
111+
new Source { Name = "Jane", Age = 25 }
112+
};
113+
114+
var destinationList = ValueMapper.MapList<Source, Destination>(sourceList);
115+
```
116+
117+
### Enum Mapping (Case-Insensitive)
118+
119+
```csharp
120+
public enum SampleEnum
121+
{
122+
None,
123+
Value1,
124+
Value2
125+
}
126+
127+
public class Source
128+
{
129+
public string EnumValue { get; set; } // Can be "Value1" or "value1"
130+
}
131+
132+
public class Destination
133+
{
134+
public SampleEnum EnumValue { get; set; }
135+
}
136+
```
137+
138+
### Type Conversion Support
139+
140+
```csharp
141+
public class Source
142+
{
143+
public int IntValue { get; set; }
144+
public double DoubleValue { get; set; }
145+
public string StringNumber { get; set; }
146+
}
147+
148+
public class Destination
149+
{
150+
public long LongValue { get; set; } // Converts from int
151+
public float FloatValue { get; set; } // Converts from double
152+
public int IntFromString { get; set; } // Converts from string
153+
}
154+
```
155+
156+
### Nullable Handling
157+
158+
```csharp
159+
public class Source
160+
{
161+
public string Value { get; set; } // Can be null
162+
}
163+
164+
public class Destination
165+
{
166+
public int? NullableValue { get; set; } // Will be null if source is null
167+
}
168+
```
169+
170+
## Performance
171+
172+
ValueMapper is designed for high performance. Here are some benchmark results comparing it with other popular mappers:
173+
174+
### Performance Comparison
175+
176+
#### Single Object Mapping (Relative to Manual Implementation)
177+
178+
| Mapper | Performance | Relative Slowdown |
179+
| ------------------- | ----------- | ----------------- |
180+
| Manual (baseline) | 0.000ms | 1x |
181+
| ValueMapper | 0.001ms | 11.95x slower |
182+
| AutoMapper | 0.002ms | 12.67x slower |
183+
| Mapster | 0.001ms | 8.11x slower |
184+
| ManuallyImplemented | 0.001ms | 7.29x slower |
185+
186+
#### Collection Mapping (100,000 items)
187+
188+
| Mapper | Time per Operation |
189+
| ----------------------------- | ------------------ |
190+
| ValueMapperCollection | 39.840ms |
191+
| AutoMapperCollection | 70.800ms |
192+
| MapsterCollection | 65.340ms |
193+
| ManuallyImplementedCollection | 45.310ms |
194+
195+
#### Warmup Performance (First-time Use)
196+
197+
| Mapper | Warmup Time |
198+
| ------------------- | ---------------- |
199+
| ValueMapper | 0ms |
200+
| AutoMapper | 7ms |
201+
| Mapster | 10ms |
202+
| ManuallyImplemented | No warmup needed |
203+
204+
### Key Performance Insights:
205+
206+
1. **Single Object Mapping**:
207+
208+
- All mappers show minimal overhead for single object mapping
209+
- Mapster shows the best performance among the automated mappers
210+
- ValueMapper performs similarly to other popular mappers
211+
212+
2. **Collection Mapping**:
213+
214+
- ValueMapper shows strong performance with large collections
215+
- ~43% faster than Mapster
216+
- ~77% faster than AutoMapper
217+
- Close to manually implemented mapping performance
218+
219+
3. **Warmup Time**:
220+
- ValueMapper has excellent cold start performance
221+
- No significant warmup overhead
222+
- Better startup time compared to both Mapster and AutoMapper
223+
224+
Run the benchmarks yourself:
225+
226+
```shell
227+
cd ValueMapper/Benchmark
228+
dotnet run # Full benchmarks
229+
dotnet run quick # Quick benchmarks
230+
```
231+
232+
## Cache Management
233+
234+
```csharp
235+
// Clear all caches
236+
ValueMapper.ClearCaches();
237+
238+
// Pre-warm mapping for specific types
239+
ValueMapper.PreWarmMapping<Source, Destination>();
240+
241+
// Clear cache for specific types
242+
ValueMapper.Clear<Source, Destination>();
243+
```
244+
245+
## Known Limitations
246+
247+
1. Deep object mapping is not currently supported
248+
249+
- The `Map_DeepObjectMapping_ShouldMapCorrectly` test demonstrates this limitation
250+
- Complex nested objects with multiple levels are not automatically mapped
251+
252+
2. No circular reference detection
253+
3. No support for mapping private properties
254+
4. Collection type conversion (e.g., List<T> to Array<T>) is not supported
255+
5. No support for custom value converters
256+
6. No support for conditional mapping
257+
258+
## Contributing
259+
260+
Contributions are welcome! Please feel free to submit a Pull Request.
261+
262+
## License
263+
264+
This project is licensed under the MIT License - see the LICENSE file for details.
265+
266+
```
267+
268+
```

0 commit comments

Comments
 (0)