public void RegisterObject(object obj, long objectID, SerializationInfo info, long idOfContainingObj, MemberInfo member, int[] arrayIndex)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(obj));
}
if (objectID <= 0)
{
throw new ArgumentOutOfRangeException(nameof(objectID), SR.ArgumentOutOfRange_ObjectID);
}
if (member != null && !(member is FieldInfo))
{
throw new SerializationException(SR.Serialization_UnknownMemberInfo);
}
ObjectHolder temp;
ISerializationSurrogate surrogate = null;
ISurrogateSelector useless;
if (_selector != null)
{
Type selectorType = CanCallGetType(obj) ?
obj.GetType() :
typeof(MarshalByRefObject);
//If we need a surrogate for this object, lets find it now.
surrogate = _selector.GetSurrogate(selectorType, _context, out useless);
}
//The object is interested in DeserializationEvents so lets register it.
if (obj is IDeserializationCallback)
{
DeserializationEventHandler d = new DeserializationEventHandler(((IDeserializationCallback)obj).OnDeserialization);
AddOnDeserialization(d);
}
//Formatter developers may cache and reuse arrayIndex in their code.
//So that we don't get bitten by this, take a copy up front.
if (arrayIndex != null)
{
arrayIndex = (int[])arrayIndex.Clone();
}
//This is the first time which we've seen the object, we need to create a new holder.
temp = FindObjectHolder(objectID);
if (temp == null)
{
temp = new ObjectHolder(obj, objectID, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex);
AddObjectHolder(temp);
if (temp.RequiresDelayedFixup)
{
SpecialFixupObjects.Add(temp);
}
// We cannot compute whether this has any fixups required or not
AddOnDeserialized(obj);
return;
}
//If the object isn't null, we've registered this before. Not good.
if (temp.ObjectValue != null)
{
throw new SerializationException(SR.Serialization_RegisterTwice);
}
//Complete the data in the ObjectHolder
temp.UpdateData(obj, info, surrogate, idOfContainingObj, (FieldInfo)member, arrayIndex, this);
// The following case will only be true when somebody has registered a fixup on an object before
// registering the object itself. I don't believe that most well-behaved formatters will do this,
// but we need to allow it anyway. We will walk the list of fixups which have been recorded on
// the new object and fix those that we can. Because the user could still register later fixups
// on this object, we won't call any implementations of ISerializable now. If that's required,
// it will have to be handled by the code in DoFixups.
// README README: We have to do the UpdateData before
if (temp.DirectlyDependentObjects > 0)
{
CompleteObject(temp, false);
}
if (temp.RequiresDelayedFixup)
{
SpecialFixupObjects.Add(temp);
}
if (temp.CompletelyFixed)
{
//Here's where things get tricky. If this isn't an instance of IObjectReference, we need to walk it's fixup
//chain and decrement the counters on anything that has reached 0. Once we've notified all of the dependencies,
//we can simply clear the list of dependent objects.
DoNewlyRegisteredObjectFixups(temp);
temp.DependentObjects = null;
}
//Register the OnDeserialized methods to be invoked after deserialization is complete
if (temp.TotalDependentObjects > 0)
{
AddOnDeserialized(obj);
}
else
{
RaiseOnDeserializedEvent(obj);
}
}