Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/DbReader.Tests/InstanceReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,17 @@ public void ShouldUseDefaultValue()
instance.Property.Value.ShouldBe(42);
}

[Fact]
public void ShouldNotUseDefaultValue()
{
var dataRecord = new { Id = 1, Property = 42 }.ToDataRecord();
DbReaderOptions.WhenReading<CustomValueType>().Use((dr, i) => new CustomValueType(dr.GetInt32(i))).WithDefaultValue(new CustomValueType(82));
var reader = GetReader<ClassWithProperty<CustomValueType>>();
var instance = reader.Read(dataRecord, string.Empty);
instance.Property.Value.ShouldBe(42);
}



public class CustomValueType
{
Expand Down
4 changes: 2 additions & 2 deletions src/DbReader/Construction/ConstructorReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/// an instance of <typeparamref name="T"/> using constructor arguments.
/// </summary>
/// <typeparam name="T">The type of object to be created.</typeparam>
public class ConstructorReaderMethodBuilder<T> : ReaderMethodBuilder<T>
public class ConstructorReaderMethodBuilder<T> : ReaderMethodBuilder<T>
{
private readonly IConstructorSelector constructorSelector;

Expand Down Expand Up @@ -50,7 +50,7 @@ private void LoadConstructorArguments(ILGenerator il, ConstructorInfo constructo
for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
{
EmitCheckForValidOrdinal(il, parameterIndex, tryLoadNullValue);
EmitCheckForDbNull(il, parameterIndex, tryLoadNullValue);
EmitGoLabelIfDbNull(il, parameterIndex, tryLoadNullValue);
}

for (int i = 0; i < parameters.Length; i++)
Expand Down
10 changes: 7 additions & 3 deletions src/DbReader/Construction/PropertyReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,16 @@ private void EmitPropertySetters(ILGenerator generator, LocalBuilder instanceVar
private void EmitPropertySetter(ILGenerator il, PropertyInfo property, int propertyIndex, LocalBuilder instanceVariable)
{
MethodInfo getMethod = MethodSelector.Execute(property.PropertyType);
var checkForDefaultValueLabel = il.DefineLabel();
var endLabel = il.DefineLabel();
EmitCheckForValidOrdinal(il, propertyIndex, endLabel);
EmitCheckForDbNull(il, propertyIndex, endLabel);
EmitCheckForValidOrdinal(il, propertyIndex, checkForDefaultValueLabel);
EmitGoLabelIfDbNull(il, propertyIndex, checkForDefaultValueLabel);
LoadInstance(il, instanceVariable);
EmitGetValue(il, propertyIndex, getMethod, property.PropertyType);
EmitCallPropertySetterMethod(il, property);
il.MarkLabel(endLabel);
il.MarkLabel(checkForDefaultValueLabel);
EmitCheckForValidOrdinal(il, propertyIndex, endLabel);
EmitGoLabelIfNotDbNull(il, propertyIndex, endLabel);
if (ValueConverter.HasDefaultValue(property.PropertyType))
{
var openGenericGetDefaultValueMethod = typeof(ValueConverter).GetMethod(nameof(ValueConverter.GetDefaultValue), BindingFlags.Static | BindingFlags.NonPublic);
Expand All @@ -148,6 +151,7 @@ private void EmitPropertySetter(ILGenerator il, PropertyInfo property, int prope
il.Emit(OpCodes.Call, getDefaultValueMethod);
EmitCallPropertySetterMethod(il, property);
}
il.MarkLabel(endLabel);
}
}
}
23 changes: 18 additions & 5 deletions src/DbReader/Construction/ReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
LoadOrdinal(il, index);
LoadIntegerValueOfMinusOne(il);
EmitCompareValues(il);
EmitGotoEndLabelIfValueIsTrue(il, trueLabel);
EmitGotoLabelIfValueIsTrue(il, trueLabel);
}

/// <summary>
Expand All @@ -76,12 +76,20 @@
/// <param name="index">The index of the ordinal to check.</param>
/// <param name="trueLabel">The <see cref="Label"/> that represents where to jump if
/// the value about to be read from the <see cref="IDataRecord"/> is <see cref="DBNull"/>.</param>
protected void EmitCheckForDbNull(ILGenerator il, int index, Label trueLabel)
protected void EmitGoLabelIfDbNull(ILGenerator il, int index, Label trueLabel)
{
LoadDataRecord(il);
LoadOrdinal(il, index);
EmitCallIsDbNullMethod(il);
EmitGotoEndLabelIfValueIsTrue(il, trueLabel);
EmitGotoLabelIfValueIsTrue(il, trueLabel);
}

protected void EmitGoLabelIfNotDbNull(ILGenerator il, int index, Label falseLabel)

Check warning on line 87 in src/DbReader/Construction/ReaderMethodBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ReaderMethodBuilder<T>.EmitGoLabelIfNotDbNull(ILGenerator, int, Label)'

Check warning on line 87 in src/DbReader/Construction/ReaderMethodBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ReaderMethodBuilder<T>.EmitGoLabelIfNotDbNull(ILGenerator, int, Label)'
{
LoadDataRecord(il);
LoadOrdinal(il, index);
EmitCallIsDbNullMethod(il);
EmitGotoLabelIfValueIsFalse(il, falseLabel);
}

/// <summary>
Expand Down Expand Up @@ -168,9 +176,14 @@
il.Emit(OpCodes.Ceq);
}

private static void EmitGotoEndLabelIfValueIsTrue(ILGenerator il, Label endLabel)
private static void EmitGotoLabelIfValueIsTrue(ILGenerator il, Label trueLabel)
{
il.Emit(OpCodes.Brtrue, trueLabel);
}

private static void EmitGotoLabelIfValueIsFalse(ILGenerator il, Label trueLabel)
{
il.Emit(OpCodes.Brtrue, endLabel);
il.Emit(OpCodes.Brfalse, trueLabel);
}

private static Func<IDataRecord, int[], T> CreateDelegate(IMethodSkeleton methodSkeleton)
Expand Down
Loading