UnitTests/BinarySerialisationVersioningTests.cs
/// <summary>
/// This is the same principle as AllDeserialisationIfFieldCanNotBeSetIfFieldIsMarkedAsOptionalForDeserialisation but for the case where there is an auto-property that has
/// the [OptionalWhenDeserialising] attribute on it
/// </summary>
This is the same principle as AllDeserialisationIfFieldCanNotBeSetIfFieldIsMarkedAsOptionalForDeserialisation but for the case where there is an auto-property that has
the [OptionalWhenDeserialising] attribute on it
This is the same principle as AllDeserialisationIfFieldCanNotBeSetIfFieldIsMarkedAsOptionalForDeserialisation but for the case where there is an auto - property that has the [ OptionalWhenDeserialising ] attribute on it
[Fact]
		public static void AllowDeserialisationIfFieldCanNotBeSetIfFieldIsForAutoPropertyThatIsMarkedAsOptionalForDeserialisation()
		{
			var sourceType = ConstructType(GetModuleBuilder("DynamicAssemblyFor" + GetMyName(), new Version(1, 0)), "MyClass", new Tuple<string, Type>[0]);
			var instance = Activator.CreateInstance(sourceType);
			var serialisedData = BinarySerialisation.Serialise(instance);
			const string namePropertyName = "Name";
			var destinationType = ConstructType(
				GetModuleBuilder("DynamicAssemblyFor" + GetMyName(), new Version(1, 0)),
				"MyClass",
				fields: new Tuple<string, Type>[0],
				optionalFinisher: typeBuilder =>
				{
					var fieldBuilder = typeBuilder.DefineField(BackingFieldHelpers.GetBackingFieldName(namePropertyName), typeof(string), FieldAttributes.Private);
					var propertyBuilder = typeBuilder.DefineProperty(namePropertyName, PropertyAttributes.None, typeof(string), parameterTypes: Type.EmptyTypes);
					propertyBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(DeprecatedAttribute).GetConstructor(new[] { typeof(string) }), new object[] { null }));
					var getterBuilder = typeBuilder.DefineMethod("get_" + namePropertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(string), parameterTypes: Type.EmptyTypes);
					var ilGenerator = getterBuilder.GetILGenerator();
					ilGenerator.Emit(OpCodes.Ldarg_0);
					ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);
					ilGenerator.Emit(OpCodes.Ret);
					propertyBuilder.SetGetMethod(getterBuilder);
					propertyBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(OptionalWhenDeserialisingAttribute).GetConstructor(Type.EmptyTypes), new object[0]));
				}
			);
			var clone = ResolveDynamicAssembliesWhilePerformingAction(
				() => Deserialise(serialisedData, destinationType),
				destinationType
			);
			var namePropertyOnDestination = destinationType.GetProperty(namePropertyName);
			Assert.Null(namePropertyOnDestination.GetValue(clone));
		}
[ Fact ] public static void AllowDeserialisationIfFieldCanNotBeSetIfFieldIsForAutoPropertyThatIsMarkedAsOptionalForDeserialisation ( ) { var sourceType = ConstructType ( GetModuleBuilder ( " " + GetMyName ( ) , new Version ( 1 , 0 ) ) , " " , new Tuple < string , Type > [ 0 ] ) ; var instance = Activator . CreateInstance ( sourceType ) ; var serialisedData = BinarySerialisation . Serialise ( instance ) ; const string namePropertyName = " " ; var destinationType = ConstructType ( GetModuleBuilder ( " " + GetMyName ( ) , new Version ( 1 , 0 ) ) , " " , fields : new Tuple < string , Type > [ 0 ] , optionalFinisher : typeBuilder => { var fieldBuilder = typeBuilder . DefineField ( BackingFieldHelpers . GetBackingFieldName ( namePropertyName ) , typeof ( string ) , FieldAttributes . Private ) ; var propertyBuilder = typeBuilder . DefineProperty ( namePropertyName , PropertyAttributes . None , typeof ( string ) , parameterTypes : Type . EmptyTypes ) ; propertyBuilder . SetCustomAttribute ( new CustomAttributeBuilder ( typeof ( DeprecatedAttribute ) . GetConstructor ( new [ ] { typeof ( string ) } ) , new object [ ] { null } ) ) ; var getterBuilder = typeBuilder . DefineMethod ( " " + namePropertyName , MethodAttributes . Public | MethodAttributes . SpecialName | MethodAttributes . HideBySig , typeof ( string ) , parameterTypes : Type . EmptyTypes ) ; var ilGenerator = getterBuilder . GetILGenerator ( ) ; ilGenerator . Emit ( OpCodes . Ldarg_0 ) ; ilGenerator . Emit ( OpCodes . Ldfld , fieldBuilder ) ; ilGenerator . Emit ( OpCodes . Ret ) ; propertyBuilder . SetGetMethod ( getterBuilder ) ; propertyBuilder . SetCustomAttribute ( new CustomAttributeBuilder ( typeof ( OptionalWhenDeserialisingAttribute ) . GetConstructor ( Type . EmptyTypes ) , new object [ 0 ] ) ) ; } ) ; var clone = ResolveDynamicAssembliesWhilePerformingAction ( ( ) => Deserialise ( serialisedData , destinationType ) , destinationType ) ; var namePropertyOnDestination = destinationType . GetProperty ( namePropertyName ) ; Assert . Null ( namePropertyOnDestination . GetValue ( clone ) ) ; }
This is the same principle as AllDeserialisationIfFieldCanNotBeSetIfFieldIsMarkedAsOptionalForDeserialisation but for the case where there is an auto-property that has
the [OptionalWhenDeserialising] attribute on it
This is the same principle as AllDeserialisationIfFieldCanNotBeSetIfFieldIsMarkedAsOptionalForDeserialisation but for the case where there is an auto - property that has the [ OptionalWhenDeserialising ] attribute on it
// Need to define the field using this lambda rather than specifying it through the fields argument because we need the reference for use in the property getter