Lambda expressions are a powerful feature of the .NET stack, allowing developers to “express” an operation. Some of the most popular OSS libraries in .NET today take advantage of expressions: FluentValidation, AutoMapper, Dapper, and Marten. Library authors use expressions to help interpret a user’s intent into executable code, and most commonly used in LINQ implementations. Expressions can be beneficial in code-as-configuration scenarios, where our types and values are .NET objects.
In this short yet valuable post, we’ll implement extension methods that allow us to retrieve the PropertyInfo
of a lambda expression, helpful in building our expression-powered APIs.
Using Expressions For Mapping
First, let’s look at an example that might look familiar to users of AutoMapper.
Where are taking a source and mapping it to a target destination. The API of our Mapper
type might look something like this. I’ve left out internal implementation for brevity.
From here, we can access the type of our targets and destinations, and with the additional member expressions, we can also retrieve the PropertyInfo
defined by the developer.
While this approach is contrived, we could use the mapping information for processing values as we map into our target destination from the source. A good example might be transforming sensitive data like credit card information, government identifiers, and date of birth.
Now that we have expressions, how do we retrieve the PropertyInfo
of an expression x => x.Id
?
Retrieving PropertyInfo From A Lambda Expression
We can use the System.Linq.Expressions
namespace to work through the user-defined expression.
Example usages from a unit testing class show how to use the extension methods.
We have the added benefit of having access to PropertyInfo
, which allows us to set the value of any property at runtime. We can use the method SetValue
and an instance of our target type. Pretty cool!
Conclusion
Expressions are a powerful feature of the .NET stack as they can help users express intent ahead of time. In OSS libraries like FluentValidation and Automapper, developers use expressions as in-code configuration. If you’re planning on building a similar API, be prepared for many generics, expressions, and reflections. A warning to developers, reflection can come at a performance expense. Developers should measure their implementation and its impacts during real-world scenarios.
I hope you found this post helpful, and thanks again for reading.