diff --git a/Realm.Shared/Dynamic/DynamicRealmObjectHelper.cs b/Realm.Shared/Dynamic/DynamicRealmObjectHelper.cs index 56ad91f847..705551377a 100644 --- a/Realm.Shared/Dynamic/DynamicRealmObjectHelper.cs +++ b/Realm.Shared/Dynamic/DynamicRealmObjectHelper.cs @@ -27,35 +27,35 @@ internal class DynamicRealmObjectHelper : IRealmObjectHelper { internal static readonly DynamicRealmObjectHelper Instance = new DynamicRealmObjectHelper(); - public void CopyToRealm(RealmObject instance) - { - foreach (var property in instance.ObjectSchema) - { - var field = property.PropertyInfo.DeclaringType.GetField( - property.PropertyInfo.GetCustomAttribute().BackingFieldName, - BindingFlags.Instance | BindingFlags.NonPublic - ); - var value = field?.GetValue(this); - if (value != null) - { - var listValue = value as IEnumerable; - if (listValue != null) // assume it is IList NOT a RealmList so need to wipe afer copy - { - // cope with ReplaceListGetter creating a getter which assumes - // a backing field for a managed IList is already a RealmList, so null it first - field.SetValue(this, null); // now getter will create a RealmList below - var realmList = (ICopyValuesFrom)property.PropertyInfo.GetValue(this, null); - realmList.CopyValuesFrom(listValue); - } - else - { - property.PropertyInfo.SetValue(this, value, null); - } - } // only null if blank relationship or string so leave as default - } - } + public void CopyToRealm(RealmObject instance) + { + foreach (var property in instance.ObjectSchema) + { + var field = property.PropertyInfo.DeclaringType.GetField( + property.PropertyInfo.GetCustomAttribute().BackingFieldName, + BindingFlags.Instance | BindingFlags.NonPublic + ); + var value = field?.GetValue(this); + if (value != null) + { + var listValue = value as IEnumerable; + if (listValue != null) // assume it is IList NOT a RealmList so need to wipe afer copy + { + // cope with ReplaceListGetter creating a getter which assumes + // a backing field for a managed IList is already a RealmList, so null it first + field.SetValue(this, null); // now getter will create a RealmList below + var realmList = (ICopyValuesFrom)property.PropertyInfo.GetValue(this, null); + realmList.CopyValuesFrom(listValue); + } + else + { + property.PropertyInfo.SetValue(this, value, null); + } + } // only null if blank relationship or string so leave as default + } + } - public RealmObject CreateInstance() + public RealmObject CreateInstance() { return new DynamicRealmObject(); } diff --git a/Realm.Shared/ICopyValuesFrom.cs b/Realm.Shared/ICopyValuesFrom.cs index a754075e73..c35e0eea84 100644 --- a/Realm.Shared/ICopyValuesFrom.cs +++ b/Realm.Shared/ICopyValuesFrom.cs @@ -4,7 +4,7 @@ namespace Realms { // Interface allows us to cast a generic RealmList to this and invoke CopyValuesFrom - public interface ICopyValuesFrom + public interface ICopyValuesFrom { void CopyValuesFrom(IEnumerable values); } diff --git a/Realm.Shared/RealmList.cs b/Realm.Shared/RealmList.cs index fcb598dfec..ff8f9a4777 100755 --- a/Realm.Shared/RealmList.cs +++ b/Realm.Shared/RealmList.cs @@ -315,10 +315,10 @@ private void ManageObjectIfNeeded(T obj) void ICopyValuesFrom.CopyValuesFrom(IEnumerable values) { - if (values == null) - { - return; - } + if (values == null) + { + return; + } foreach (var item in values.Cast()) { diff --git a/Realm.Shared/RealmObject.cs b/Realm.Shared/RealmObject.cs index ce6c8faffb..0fbb56288f 100644 --- a/Realm.Shared/RealmObject.cs +++ b/Realm.Shared/RealmObject.cs @@ -88,7 +88,7 @@ internal class Metadata internal void _CopyDataFromBackingFieldsToRow() { Debug.Assert(this.IsManaged); - _metadata.Helper.CopyToRealm(this); + _metadata.Helper.CopyToRealm(this); } #region Getters diff --git a/Realm.Shared/weaving/IRealmObjectHelper.cs b/Realm.Shared/weaving/IRealmObjectHelper.cs index d6d02e82fe..c14950f5cd 100644 --- a/Realm.Shared/weaving/IRealmObjectHelper.cs +++ b/Realm.Shared/weaving/IRealmObjectHelper.cs @@ -22,6 +22,6 @@ public interface IRealmObjectHelper { RealmObject CreateInstance(); - void CopyToRealm(RealmObject instance); + void CopyToRealm(RealmObject instance); } } \ No newline at end of file diff --git a/RealmWeaver/ModuleWeaver.cs b/RealmWeaver/ModuleWeaver.cs index 10409ae7f5..e2c0357c97 100644 --- a/RealmWeaver/ModuleWeaver.cs +++ b/RealmWeaver/ModuleWeaver.cs @@ -15,7 +15,7 @@ // limitations under the License. // //////////////////////////////////////////////////////////////////////////// - + using System; using System.Linq; using Mono.Cecil; @@ -109,8 +109,8 @@ public class ModuleWeaver private MethodReference _wovenAttributeConstructor; private MethodReference _wovenPropertyAttributeConstructor; - private TypeDefinition _icopyValuesFrom; - private MethodReference _icopyValuesFrom_CopyValuesFromMethod; + private TypeDefinition _icopyValuesFrom; + private MethodReference _icopyValuesFrom_CopyValuesFromMethod; private IEnumerable GetMatchingTypes() { @@ -152,8 +152,8 @@ public void Execute() _realmObject = _realmAssembly.MainModule.GetTypes().First(x => x.Name == "RealmObject"); _realmObjectIsManagedGetter = ModuleDefinition.ImportReference(_realmObject.Properties.Single(x => x.Name == "IsManaged").GetMethod); - _icopyValuesFrom = _realmAssembly.MainModule.GetType("Realms.ICopyValuesFrom"); - _icopyValuesFrom_CopyValuesFromMethod = ModuleDefinition.ImportReference(_icopyValuesFrom.Methods.Single(x => x.Name == "CopyValuesFrom")); + _icopyValuesFrom = _realmAssembly.MainModule.GetType("Realms.ICopyValuesFrom"); + _icopyValuesFrom_CopyValuesFromMethod = ModuleDefinition.ImportReference(_icopyValuesFrom.Methods.Single(x => x.Name == "CopyValuesFrom")); // Cache of getter and setter methods for the various types. var methodTable = new Dictionary>(); @@ -173,7 +173,7 @@ public void Execute() _wovenPropertyAttributeConstructor = ModuleDefinition.ImportReference(wovenPropertyAttributeClass.GetConstructors().First()); _corLib = AssemblyResolver.Resolve((AssemblyNameReference)ModuleDefinition.TypeSystem.CoreLibrary); - System_Object = ModuleDefinition.TypeSystem.Object; + System_Object = ModuleDefinition.TypeSystem.Object; System_Boolean = ModuleDefinition.TypeSystem.Boolean; System_String = ModuleDefinition.TypeSystem.String; var typeTypeDefinition = _corLib.MainModule.GetType("System.Type"); @@ -220,7 +220,7 @@ public void Execute() } catch (Exception e) { - LogError( $"Unexpected error caught weaving type '{type.Name}': {e.Message}.\r\nCallstack:\r\n{e.StackTrace}"); + LogError($"Unexpected error caught weaving type '{type.Name}': {e.Message}.\r\nCallstack:\r\n{e.StackTrace}"); } } @@ -233,7 +233,7 @@ private void WeaveType(TypeDefinition type, Dictionary t.FullName == "System.ComponentModel.INotifyPropertyChanged"); - + EventDefinition propChangedEventDefinition = null; FieldDefinition propChangedFieldDefinition = null; @@ -243,17 +243,17 @@ private void WeaveType(TypeDefinition type, Dictionary X.FullName.EndsWith("::PropertyChanged")); } - var persistedProperties = new Dictionary(); - foreach (var prop in type.Properties.Where( x => x.HasThis && !x.CustomAttributes.Any(a => a.AttributeType.Name == "IgnoredAttribute"))) + var persistedProperties = new Dictionary(); + foreach (var prop in type.Properties.Where(x => x.HasThis && !x.CustomAttributes.Any(a => a.AttributeType.Name == "IgnoredAttribute"))) { try { - FieldReference field; + FieldReference field; var wasWoven = WeaveProperty(prop, type, methodTable, typeImplementsPropertyChanged, propChangedEventDefinition, propChangedFieldDefinition, out field); if (wasWoven) - { - persistedProperties[prop] = field; - } + { + persistedProperties[prop] = field; + } } catch (Exception e) { @@ -264,7 +264,7 @@ private void WeaveType(TypeDefinition type, Dictionary> methodTable, - bool typeImplementsPropertyChanged, EventDefinition propChangedEventDefinition, - FieldDefinition propChangedFieldDefinition, out FieldReference backingField) + private bool WeaveProperty(PropertyDefinition prop, TypeDefinition type, Dictionary> methodTable, + bool typeImplementsPropertyChanged, EventDefinition propChangedEventDefinition, + FieldDefinition propChangedFieldDefinition, out FieldReference backingField) { var sequencePoint = prop.GetMethod.Body.Instructions.First().SequencePoint; var columnName = prop.Name; var mapToAttribute = prop.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "MapToAttribute"); if (mapToAttribute != null) - columnName = ((string) mapToAttribute.ConstructorArguments[0].Value); + columnName = ((string)mapToAttribute.ConstructorArguments[0].Value); backingField = GetBackingField(prop); var isIndexed = prop.CustomAttributes.Any(a => a.AttributeType.Name == "IndexedAttribute"); @@ -326,7 +326,7 @@ private bool WeaveProperty(PropertyDefinition prop, TypeDefinition type, Diction return false; } - if (!prop.IsAutomatic()) + if (!prop.IsAutomatic()) { if (prop.PropertyType.Resolve().BaseType.IsSameAs(_realmObject)) LogWarningPoint( @@ -339,7 +339,7 @@ private bool WeaveProperty(PropertyDefinition prop, TypeDefinition type, Diction // If the property is automatic but doesn't have a setter, we should still ignore it. if (prop.SetMethod == null) return false; - + var typeId = prop.PropertyType.FullName + (isPrimaryKey ? " unique" : ""); if (!methodTable.ContainsKey(typeId)) { @@ -355,7 +355,7 @@ private bool WeaveProperty(PropertyDefinition prop, TypeDefinition type, Diction // treat IList and RealmList similarly but IList gets a default so is useable as standalone // IList or RealmList allows people to declare lists only of _realmObject due to the class definition - else if (IsIList(prop)) + else if (IsIList(prop)) { var elementType = ((GenericInstanceType)prop.PropertyType).GenericArguments.Single(); if (!elementType.Resolve().BaseType.IsSameAs(_realmObject)) @@ -412,11 +412,11 @@ private bool WeaveProperty(PropertyDefinition prop, TypeDefinition type, Diction } ReplaceGetter(prop, columnName, - new GenericInstanceMethod(_genericGetObjectValueReference) {GenericArguments = {prop.PropertyType}}); + new GenericInstanceMethod(_genericGetObjectValueReference) { GenericArguments = { prop.PropertyType } }); ReplaceSetter(prop, backingField, columnName, - new GenericInstanceMethod(_genericSetObjectValueReference) {GenericArguments = {prop.PropertyType}}, + new GenericInstanceMethod(_genericSetObjectValueReference) { GenericArguments = { prop.PropertyType } }, typeImplementsPropertyChanged, propChangedEventDefinition, propChangedFieldDefinition); - // with casting in the _realmObject methods, should just work + // with casting in the _realmObject methods, should just work } else if (prop.PropertyType.FullName == "System.DateTime") { @@ -644,7 +644,7 @@ void ReplaceSetter(PropertyDefinition prop, FieldReference backingField, string if (setValueReference == null) throw new ArgumentNullException(nameof(setValueReference)); - + if (!weavePropertyChanged) { var start = prop.SetMethod.Body.Instructions.First(); @@ -707,12 +707,12 @@ void ReplaceSetter(PropertyDefinition prop, FieldReference backingField, string ldloc.1 brfalse.s IL_0017 */ - il.Append(il.Create(OpCodes.Ldarg_0)); + il.Append(il.Create(OpCodes.Ldarg_0)); il.Append(il.Create(OpCodes.Call, _realmObjectIsManagedGetter)); - il.Append(il.Create(OpCodes.Ldc_I4_0)); - il.Append(il.Create(OpCodes.Ceq)); - il.Append(il.Create(OpCodes.Stloc_1)); - il.Append(il.Create(OpCodes.Ldloc_1)); + il.Append(il.Create(OpCodes.Ldc_I4_0)); + il.Append(il.Create(OpCodes.Ceq)); + il.Append(il.Create(OpCodes.Stloc_1)); + il.Append(il.Create(OpCodes.Ldloc_1)); var jumpToLabelA = il.Create(OpCodes.Nop); il.Append(jumpToLabelA); // Jump to A @@ -800,17 +800,17 @@ private static FieldReference GetBackingField(PropertyDefinition property) .SingleOrDefault(); } - private static bool IsIList(PropertyDefinition property) - { - return property.PropertyType.Name == "IList`1" && property.PropertyType.Namespace == "System.Collections.Generic"; - } + private static bool IsIList(PropertyDefinition property) + { + return property.PropertyType.Name == "IList`1" && property.PropertyType.Namespace == "System.Collections.Generic"; + } - private static bool IsRealmList(PropertyDefinition property) - { - return property.PropertyType.Name == "RealmList`1" && property.PropertyType.Namespace == "Realms"; - } + private static bool IsRealmList(PropertyDefinition property) + { + return property.PropertyType.Name == "RealmList`1" && property.PropertyType.Namespace == "Realms"; + } - private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, MethodDefinition objectConstructor, IDictionary properties) + private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, MethodDefinition objectConstructor, IDictionary properties) { var helperType = new TypeDefinition(null, "RealmHelper", TypeAttributes.Class | TypeAttributes.NestedPrivate | TypeAttributes.BeforeFieldInit, @@ -826,10 +826,10 @@ private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, Me } helperType.Methods.Add(createInstance); - var copyToRealm = new MethodDefinition("CopyToRealm", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot, ModuleDefinition.TypeSystem.Void); - { - // This roughly translates to - /* + var copyToRealm = new MethodDefinition("CopyToRealm", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot, ModuleDefinition.TypeSystem.Void); + { + // This roughly translates to + /* var casted = (ObjectType)instance; *foreach* non-list woven property in casted's schema @@ -841,58 +841,58 @@ private TypeDefinition WeaveRealmObjectHelper(TypeDefinition realmObjectType, Me ((ICopyValuesFrom)casted.Property).CopyValuesFrom(list); */ - var instanceParameter = new ParameterDefinition("instance", ParameterAttributes.None, ModuleDefinition.ImportReference(_realmObject)); - copyToRealm.Parameters.Add(instanceParameter); - - foreach (var kvp in properties.Where(kvp => IsIList(kvp.Key) || IsRealmList(kvp.Key))) - { - copyToRealm.Body.Variables.Add(new VariableDefinition(ModuleDefinition.ImportReference(kvp.Value.FieldType))); - } - - var il = copyToRealm.Body.GetILProcessor(); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Castclass, ModuleDefinition.ImportReference(realmObjectType)); - - byte currentStloc = 0; - foreach (var kvp in properties) - { - var property = kvp.Key; - var field = kvp.Value; - if (property.SetMethod != null) - { - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Ldfld, field); - il.Emit(OpCodes.Call, ModuleDefinition.ImportReference(property.SetMethod)); - } - else if (IsIList(property) || IsRealmList(property)) - { - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Ldfld, field); - il.Emit(OpCodes.Stloc_S, currentStloc); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Ldnull); - il.Emit(OpCodes.Stfld, field); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(property.GetMethod)); - il.Emit(OpCodes.Castclass, ModuleDefinition.ImportReference(_icopyValuesFrom)); - il.Emit(OpCodes.Ldloc_S, currentStloc); - il.Emit(OpCodes.Callvirt, _icopyValuesFrom_CopyValuesFromMethod); - currentStloc++; - } - else - { - var sequencePoint = property.GetMethod.Body.Instructions.First().SequencePoint; - LogErrorPoint($"{realmObjectType.Name}.{property.Name} does not have a setter and is not an IList.", sequencePoint); - } - - } - - il.Emit(OpCodes.Pop); // We're void, so pop the last value from the stack to avoid returning it with Ret - il.Emit(OpCodes.Ret); - } - copyToRealm.CustomAttributes.Add(new CustomAttribute(_preserveAttributeConstructor)); - helperType.Methods.Add(copyToRealm); + var instanceParameter = new ParameterDefinition("instance", ParameterAttributes.None, ModuleDefinition.ImportReference(_realmObject)); + copyToRealm.Parameters.Add(instanceParameter); + + foreach (var kvp in properties.Where(kvp => IsIList(kvp.Key) || IsRealmList(kvp.Key))) + { + copyToRealm.Body.Variables.Add(new VariableDefinition(ModuleDefinition.ImportReference(kvp.Value.FieldType))); + } + + var il = copyToRealm.Body.GetILProcessor(); + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Castclass, ModuleDefinition.ImportReference(realmObjectType)); + + byte currentStloc = 0; + foreach (var kvp in properties) + { + var property = kvp.Key; + var field = kvp.Value; + if (property.SetMethod != null) + { + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldfld, field); + il.Emit(OpCodes.Call, ModuleDefinition.ImportReference(property.SetMethod)); + } + else if (IsIList(property) || IsRealmList(property)) + { + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldfld, field); + il.Emit(OpCodes.Stloc_S, currentStloc); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stfld, field); + il.Emit(OpCodes.Dup); + il.Emit(OpCodes.Callvirt, ModuleDefinition.ImportReference(property.GetMethod)); + il.Emit(OpCodes.Castclass, ModuleDefinition.ImportReference(_icopyValuesFrom)); + il.Emit(OpCodes.Ldloc_S, currentStloc); + il.Emit(OpCodes.Callvirt, _icopyValuesFrom_CopyValuesFromMethod); + currentStloc++; + } + else + { + var sequencePoint = property.GetMethod.Body.Instructions.First().SequencePoint; + LogErrorPoint($"{realmObjectType.Name}.{property.Name} does not have a setter and is not an IList.", sequencePoint); + } + + } + + il.Emit(OpCodes.Pop); // We're void, so pop the last value from the stack to avoid returning it with Ret + il.Emit(OpCodes.Ret); + } + copyToRealm.CustomAttributes.Add(new CustomAttribute(_preserveAttributeConstructor)); + helperType.Methods.Add(copyToRealm); const MethodAttributes ctorAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var ctor = new MethodDefinition(".ctor", ctorAttributes, ModuleDefinition.TypeSystem.Void); diff --git a/Tests/IntegrationTests.Shared/PerformanceTests.cs b/Tests/IntegrationTests.Shared/PerformanceTests.cs index 78f6febfb5..6fa96dcf71 100644 --- a/Tests/IntegrationTests.Shared/PerformanceTests.cs +++ b/Tests/IntegrationTests.Shared/PerformanceTests.cs @@ -129,91 +129,91 @@ public void BindingSetValuePerformanceTest(int count) Console.WriteLine("Kilo-iterations per second: {0:0.00}", ((count/1000) / sw.Elapsed.TotalSeconds)); } - [TestCase(100000), Explicit] - public void ManageSmallObjectPerformanceTest(int count) - { - var objects = new List(); - for (var i = 0; i < count; i++) - { - objects.Add(new MiniPerson - { - Name = "Name" + i, - IsInteresting = true - }); - } - - var sw = new Stopwatch(); - sw.Start(); - - _realm.Write(() => - { - foreach (var obj in objects) - { - _realm.Manage(obj); - } - }); - sw.Stop(); - Console.WriteLine($"{count} objects managed for {sw.ElapsedMilliseconds} ms"); - - sw.Restart(); - _realm.Write(() => - { - for (var i = 0; i < count; i++) - { - var newObject = _realm.CreateObject(); - newObject.Name = objects[i].Name; - newObject.IsInteresting = objects[i].IsInteresting; - } - }); - - Console.WriteLine($"{count} objects created for {sw.ElapsedMilliseconds} ms"); - } - - [TestCase(100000), Explicit] - public void ManageLargeObjectPerformanceTest(int count) - { - var objects = new List(); - for (var i = 0; i < count; i++) - { - objects.Add(new Person - { - FirstName = "Name" + i, - IsInteresting = true - }); - } - - var sw = new Stopwatch(); - sw.Start(); - - _realm.Write(() => - { - foreach (var obj in objects) - { - _realm.Manage(obj); - } - }); - sw.Stop(); - Console.WriteLine($"{count} objects managed for {sw.ElapsedMilliseconds} ms"); - - sw.Restart(); - _realm.Write(() => - { - for (var i = 0; i < count; i++) - { - var newObject = _realm.CreateObject(); - newObject.FirstName = objects[i].FirstName; - newObject.IsInteresting = objects[i].IsInteresting; - } - }); - - Console.WriteLine($"{count} objects created for {sw.ElapsedMilliseconds} ms"); - } - } - - public class MiniPerson : RealmObject - { - public string Name { get; set; } - - public bool IsInteresting { get; set; } - } + [TestCase(100000), Explicit] + public void ManageSmallObjectPerformanceTest(int count) + { + var objects = new List(); + for (var i = 0; i < count; i++) + { + objects.Add(new MiniPerson + { + Name = "Name" + i, + IsInteresting = true + }); + } + + var sw = new Stopwatch(); + sw.Start(); + + _realm.Write(() => + { + foreach (var obj in objects) + { + _realm.Manage(obj); + } + }); + sw.Stop(); + Console.WriteLine($"{count} objects managed for {sw.ElapsedMilliseconds} ms"); + + sw.Restart(); + _realm.Write(() => + { + for (var i = 0; i < count; i++) + { + var newObject = _realm.CreateObject(); + newObject.Name = objects[i].Name; + newObject.IsInteresting = objects[i].IsInteresting; + } + }); + + Console.WriteLine($"{count} objects created for {sw.ElapsedMilliseconds} ms"); + } + + [TestCase(100000), Explicit] + public void ManageLargeObjectPerformanceTest(int count) + { + var objects = new List(); + for (var i = 0; i < count; i++) + { + objects.Add(new Person + { + FirstName = "Name" + i, + IsInteresting = true + }); + } + + var sw = new Stopwatch(); + sw.Start(); + + _realm.Write(() => + { + foreach (var obj in objects) + { + _realm.Manage(obj); + } + }); + sw.Stop(); + Console.WriteLine($"{count} objects managed for {sw.ElapsedMilliseconds} ms"); + + sw.Restart(); + _realm.Write(() => + { + for (var i = 0; i < count; i++) + { + var newObject = _realm.CreateObject(); + newObject.FirstName = objects[i].FirstName; + newObject.IsInteresting = objects[i].IsInteresting; + } + }); + + Console.WriteLine($"{count} objects created for {sw.ElapsedMilliseconds} ms"); + } + } + + public class MiniPerson : RealmObject + { + public string Name { get; set; } + + public bool IsInteresting { get; set; } + } } \ No newline at end of file diff --git a/Tests/IntegrationTests.Shared/StandAloneObjectTests.cs b/Tests/IntegrationTests.Shared/StandAloneObjectTests.cs index 6a1c2ef984..b534a3f2e1 100644 --- a/Tests/IntegrationTests.Shared/StandAloneObjectTests.cs +++ b/Tests/IntegrationTests.Shared/StandAloneObjectTests.cs @@ -83,89 +83,89 @@ public void RealmObject_WhenStandalone_ShouldHaveDefaultEqualsImplementation() Assert.DoesNotThrow(() => _person.Equals(otherPerson)); } - [Test] - public void RealmObject_WhenManaged_ShouldNotThrow() - { - // This is a test to ensure that our weaver is generating valid IL regardless of property configurations - - using (var realm = Realm.GetInstance()) - { - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new NoListProperties()); - }), $"{nameof(NoListProperties)} manage failed."); - - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new OnlyListProperties()); - }), $"{nameof(OnlyListProperties)} manage failed."); - - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new MixedProperties1()); - }), $"{nameof(MixedProperties1)} manage failed."); - - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new MixedProperties2()); - }), $"{nameof(MixedProperties2)} manage failed."); - - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new OneNonListProperty()); - }), $"{nameof(OneNonListProperty)} manage failed."); - - Assert.DoesNotThrow(() => realm.Write(() => - { - realm.Manage(new OneListProperty()); - }), $"{nameof(OneListProperty)} manage failed."); - } - } - - public class NoListProperties : RealmObject - { - public string Name { get; set; } - - public int Age { get; set; } - } - - public class OnlyListProperties : RealmObject - { - public IList Friends { get; } - - public IList Enemies { get; } - } - - public class MixedProperties1 : RealmObject - { - public string Name { get; set; } - - public IList Friends { get; } - - public int Age { get; set; } - - public IList Enemies { get; } - } - - public class MixedProperties2 : RealmObject - { - public IList Friends { get; } - - public int Age { get; set; } - - public IList Enemies { get; } - - public string Name { get; set; } - } - - public class OneNonListProperty : RealmObject - { - public string Name { get; set; } - } - - public class OneListProperty : RealmObject - { - public IList People { get; } - } + [Test] + public void RealmObject_WhenManaged_ShouldNotThrow() + { + // This is a test to ensure that our weaver is generating valid IL regardless of property configurations + + using (var realm = Realm.GetInstance()) + { + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new NoListProperties()); + }), $"{nameof(NoListProperties)} manage failed."); + + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new OnlyListProperties()); + }), $"{nameof(OnlyListProperties)} manage failed."); + + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new MixedProperties1()); + }), $"{nameof(MixedProperties1)} manage failed."); + + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new MixedProperties2()); + }), $"{nameof(MixedProperties2)} manage failed."); + + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new OneNonListProperty()); + }), $"{nameof(OneNonListProperty)} manage failed."); + + Assert.DoesNotThrow(() => realm.Write(() => + { + realm.Manage(new OneListProperty()); + }), $"{nameof(OneListProperty)} manage failed."); + } + } + + public class NoListProperties : RealmObject + { + public string Name { get; set; } + + public int Age { get; set; } + } + + public class OnlyListProperties : RealmObject + { + public IList Friends { get; } + + public IList Enemies { get; } + } + + public class MixedProperties1 : RealmObject + { + public string Name { get; set; } + + public IList Friends { get; } + + public int Age { get; set; } + + public IList Enemies { get; } + } + + public class MixedProperties2 : RealmObject + { + public IList Friends { get; } + + public int Age { get; set; } + + public IList Enemies { get; } + + public string Name { get; set; } + } + + public class OneNonListProperty : RealmObject + { + public string Name { get; set; } + } + + public class OneListProperty : RealmObject + { + public IList People { get; } + } } }