Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Dapper sets properties without setters

I have a model:

    public class Model
    {
        public int Id { get;}

        public string Name { get; }

        public string AnotherName { get; }
    }

default constructor, no setters, so that we have no public setter method in a generated class by IL.

BUT Dapper somehow initialize my data. All properties are filled.

                var sql = $@"SELECT id as Id, name as Name, another_name as AnotherName FROM dapper";

                var raws = (connection.QueryAsync<Model>(sql).Result).AsList();

I've found source code and they setting by Setter method, but when I tried to get setter as Dapper does, I've got null methodInfo. Here is some Dapper source code SqlMapper:3320

                    if (specializedConstructor == null)
                    {
                        // Store the value in the property/field
                        if (item.Property != null)
                        {
                            il.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type));
                        }
                        else
                        {
                            il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
                        }
                    }

and the DefaultTypeMap.GetPropertySetter:

        internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo, Type type)
        {
            if (propertyInfo.DeclaringType == type) return propertyInfo.GetSetMethod(true);

            return propertyInfo.DeclaringType.GetProperty(
                   propertyInfo.Name,
                   BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                   Type.DefaultBinder,
                   propertyInfo.PropertyType,
                   propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(),
                   null).GetSetMethod(true);
        }

You can write sample so did I, and you'll see if your property doesn't have any setter, then setter method info will be null.

like image 643
Andriy Avatar asked Feb 06 '26 10:02

Andriy


1 Answers

https://github.com/StackExchange/Dapper/blob/main/Dapper/SqlMapper.cs#L3312-L3323
source code

It stores property in the internal Dapper model; and if the property doesn't have a setter, it sets it via the backing field.

like image 178
Andriy Avatar answered Feb 09 '26 09:02

Andriy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!