Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move BO Serialization To Contexts #6

Closed
JasonBock opened this issue Apr 12, 2024 · 0 comments
Closed

Move BO Serialization To Contexts #6

JasonBock opened this issue Apr 12, 2024 · 0 comments
Labels
enhancement New feature or request
Milestone

Comments

@JasonBock
Copy link
Owner

Right now I'm generating the code to handle serialization for BOs. It's not much, but it's repeated code that I could move into the reader and writer contexts. Then, I could change the gen'd code to call these methods in one line, which should hopefully simplify things.

In GeneratorFormatterWriterContext:

public void Write(IGeneratorSerializable value, bool isNotSealed = false)
{
	if (value is not null)
	{
		(var isReferenceDuplicate, var referenceId) = this.GetReference(value);

		if (isReferenceDuplicate)
		{
			this.Writer.Write((byte)SerializationState.Duplicate);
			this.Writer.Write(referenceId);
		}
		else
		{
			this.Writer.Write((byte)SerializationState.Value);

			if (isNotSealed)
			{
				var valueTypeName = value.GetType().AssemblyQualifiedName!;
				(var isTypeNameDuplicate, var typeNameId) = this.GetTypeName(valueTypeName);

				if (isTypeNameDuplicate)
				{
					this.Writer.Write((byte)SerializationState.Duplicate);
					this.Writer.Write(typeNameId);
				}
				else
				{
					this.Writer.Write((byte)SerializationState.Value);
					this.Writer.Write(valueTypeName);
				}
			}

			value.SetState(this);
		}
	}
	else
	{
		this.Writer.Write((byte)SerializationState.Null);
	}
}

This would be called like this:

context.Write(this.ReadProperty<ChildPropertiesData>(ParentPropertiesData.ChildContentsProperty));

In GeneratorFormatterReaderContext:

public void Read<T>(Action<T> propertyLoader, bool isNotSealed = false)
{
	switch (this.Reader.ReadStateValue())
	{
		case SerializationState.Duplicate:
			propertyLoader((T)this.GetReference(this.Reader.ReadInt32()));
			break;
		case SerializationState.Value:
			T newValue;

			if (isNotSealed)
			{
				if (this.Reader.ReadStateValue() == SerializationState.Duplicate)
				{
					newValue = this.CreateInstance<T>(this.GetTypeName(this.Reader.ReadInt32()))!;
				}
				else
				{
					var newValueTypeName = this.Reader.ReadString();
					this.AddTypeName(newValueTypeName);
					newValue = this.CreateInstance<T>(newValueTypeName)!;
				}
			}
			else
			{
				newValue = this.CreateInstance<T>()!;
			}

			((IGeneratorSerializable)newValue).GetState(this);
			propertyLoader(newValue);
			this.AddReference(newValue);
			break;
		case SerializationState.Null:
			break;
	}
}

This would be called like this:

context.Read<ChildPropertiesData>(_ => this.LoadProperty(ParentPropertiesData.ChildContentsProperty, _));

I'm not entirely thrilled with the delegate usage here, but, it does make the call to LoadProperty() optimal. Right now, calling GetReference() always returns an object (because it has to), but then passing that into LoadProperty() as an object causes LoadPropertyByReflection() to be called in CSLA, and that's not idea.

This may allow the methods around the "duplicate" dictionaries in the contexts to be private. Though I need to be careful with that, especially with the deleted list field for lists.

@JasonBock JasonBock added the enhancement New feature or request label Apr 12, 2024
@JasonBock JasonBock added this to the 0.2.0 milestone Apr 12, 2024
JasonBock added a commit that referenced this issue Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant