Skip to content

Commit c0ac1e4

Browse files
committed
Serialize system types in preparation for .NET Core.
Serialize System.Type, ConstructorInfo, FieldInfo, MethodInfo, and PropertyInfo using only basic types.
1 parent 629340b commit c0ac1e4

31 files changed

+806
-526
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.IO;
2+
using System.Runtime.Serialization.Formatters.Binary;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.ExceptionsTest
6+
{
7+
[TestFixture]
8+
public class SerializationFixture
9+
{
10+
[Test]
11+
public void InstantiationExceptionSerialization()
12+
{
13+
var formatter = new BinaryFormatter();
14+
using (var memoryStream = new MemoryStream())
15+
{
16+
formatter.Serialize(memoryStream, new InstantiationException("test", GetType()));
17+
memoryStream.Position = 0;
18+
var ex = formatter.Deserialize(memoryStream) as InstantiationException;
19+
Assert.That(ex, Is.Not.Null);
20+
Assert.That(ex.PersistentType, Is.EqualTo(GetType()));
21+
}
22+
}
23+
}
24+
}

src/NHibernate/Async/Impl/CriteriaImpl.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System;
1212
using System.Collections;
1313
using System.Collections.Generic;
14+
using System.Runtime.Serialization;
1415
using System.Text;
1516
using System.Threading;
1617
using NHibernate.Criterion;

src/NHibernate/Async/Type/ArrayType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Collections;
1313
using System.Collections.Generic;
1414
using System.Data.Common;
15+
using System.Runtime.Serialization;
1516
using NHibernate.Collection;
1617
using NHibernate.Engine;
1718
using NHibernate.Persister.Collection;
@@ -70,4 +71,4 @@ public override async Task<object> ReplaceElementsAsync(object original, object
7071
return result;
7172
}
7273
}
73-
}
74+
}

src/NHibernate/Async/Type/EntityType.cs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using NHibernate.Proxy;
1919
using NHibernate.Util;
2020
using System.Collections.Generic;
21+
using System.Runtime.Serialization;
2122

2223
namespace NHibernate.Type
2324
{
@@ -98,9 +99,9 @@ public override async Task<object> ReplaceAsync(object original, object target,
9899
{
99100
return target;
100101
}
101-
if (session.GetContextEntityIdentifier(original) == null && (await (ForeignKeys.IsTransientFastAsync(associatedEntityName, original, session, cancellationToken)).ConfigureAwait(false)).GetValueOrDefault())
102+
if (session.GetContextEntityIdentifier(original) == null && (await (ForeignKeys.IsTransientFastAsync(_associatedEntityName, original, session, cancellationToken)).ConfigureAwait(false)).GetValueOrDefault())
102103
{
103-
object copy = session.Factory.GetEntityPersister(associatedEntityName).Instantiate(null);
104+
object copy = session.Factory.GetEntityPersister(_associatedEntityName).Instantiate(null);
104105
//TODO: should this be Session.instantiate(Persister, ...)?
105106
copyCache.Add(original, copy);
106107
return copy;
@@ -129,7 +130,7 @@ public override async Task<object> ReplaceAsync(object original, object target,
129130
/// <returns>
130131
/// An instance of the object or <see langword="null" /> if the identifer was null.
131132
/// </returns>
132-
public override sealed async Task<object> NullSafeGetAsync(DbDataReader rs, string[] names, ISessionImplementor session, object owner, CancellationToken cancellationToken)
133+
public sealed override async Task<object> NullSafeGetAsync(DbDataReader rs, string[] names, ISessionImplementor session, object owner, CancellationToken cancellationToken)
133134
{
134135
cancellationToken.ThrowIfCancellationRequested();
135136
return await (ResolveIdentifierAsync(await (HydrateAsync(rs, names, session, owner, cancellationToken)).ConfigureAwait(false), session, owner, cancellationToken)).ConfigureAwait(false);
@@ -144,10 +145,10 @@ protected async Task<object> ResolveIdentifierAsync(object id, ISessionImplement
144145
{
145146
cancellationToken.ThrowIfCancellationRequested();
146147
string entityName = GetAssociatedEntityName();
147-
bool isProxyUnwrapEnabled = unwrapProxy && session.Factory
148+
bool isProxyUnwrapEnabled = _unwrapProxy && session.Factory
148149
.GetEntityPersister(entityName).IsInstrumented;
149150

150-
object proxyOrEntity = await (session.InternalLoadAsync(entityName, id, eager, IsNullable && !isProxyUnwrapEnabled, cancellationToken)).ConfigureAwait(false);
151+
object proxyOrEntity = await (session.InternalLoadAsync(entityName, id, _eager, IsNullable && !isProxyUnwrapEnabled, cancellationToken)).ConfigureAwait(false);
151152

152153
if (proxyOrEntity.IsProxy())
153154
{
@@ -178,21 +179,19 @@ public override Task<object> ResolveIdentifierAsync(object value, ISessionImplem
178179
{
179180
return Task.FromResult<object>(null);
180181
}
181-
else
182+
183+
if (IsNull(owner, session))
182184
{
183-
if (IsNull(owner, session))
184-
{
185-
return Task.FromResult<object>(null); //EARLY EXIT!
186-
}
185+
return Task.FromResult<object>(null); //EARLY EXIT!
186+
}
187187

188-
if (IsReferenceToPrimaryKey)
189-
{
190-
return ResolveIdentifierAsync(value, session, cancellationToken);
191-
}
192-
else
193-
{
194-
return LoadByUniqueKeyAsync(GetAssociatedEntityName(), _uniqueKeyPropertyName, value, session, cancellationToken);
195-
}
188+
if (IsReferenceToPrimaryKey)
189+
{
190+
return ResolveIdentifierAsync(value, session, cancellationToken);
191+
}
192+
else
193+
{
194+
return LoadByUniqueKeyAsync(GetAssociatedEntityName(), _uniqueKeyPropertyName, value, session, cancellationToken);
196195
}
197196
}
198197
catch (Exception ex)

src/NHibernate/Async/Type/SerializableType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Runtime.Serialization.Formatters.Binary;
1717
using NHibernate.Engine;
1818
using NHibernate.SqlTypes;
19+
using NHibernate.Util;
1920

2021
namespace NHibernate.Type
2122
{
@@ -56,4 +57,4 @@ public override Task<object> DisassembleAsync(object value, ISessionImplementor
5657
}
5758
}
5859
}
59-
}
60+
}

src/NHibernate/Engine/Query/QueryPlanCache.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Runtime.Serialization;
34
using NHibernate.Engine.Query.Sql;
45
using NHibernate.Hql;
56
using NHibernate.Linq;
@@ -184,19 +185,16 @@ private class HQLQueryPlanKey : IEquatable<HQLQueryPlanKey>
184185
private readonly bool shallow;
185186
private readonly HashSet<string> filterNames;
186187
private readonly int hashCode;
187-
private readonly System.Type queryTypeDiscriminator;
188-
189-
public HQLQueryPlanKey(string query, bool shallow, IDictionary<string, IFilter> enabledFilters)
190-
: this(typeof(object), query, shallow, enabledFilters)
191-
{
192-
}
188+
[NonSerialized]
189+
private System.Type queryTypeDiscriminator;
190+
private SerializableSystemType _serializableQueryTypeDiscriminator;
193191

194192
public HQLQueryPlanKey(IQueryExpression queryExpression, bool shallow, IDictionary<string, IFilter> enabledFilters)
195193
: this(queryExpression.GetType(), queryExpression.Key, shallow, enabledFilters)
196194
{
197195
}
198196

199-
protected HQLQueryPlanKey(System.Type queryTypeDiscriminator, string query, bool shallow, IDictionary<string, IFilter> enabledFilters)
197+
private HQLQueryPlanKey(System.Type queryTypeDiscriminator, string query, bool shallow, IDictionary<string, IFilter> enabledFilters)
200198
{
201199
this.queryTypeDiscriminator = queryTypeDiscriminator;
202200
this.query = query;
@@ -221,6 +219,18 @@ protected HQLQueryPlanKey(System.Type queryTypeDiscriminator, string query, bool
221219
}
222220
}
223221

222+
[OnSerializing]
223+
private void OnSerializing(StreamingContext context)
224+
{
225+
_serializableQueryTypeDiscriminator = SerializableSystemType.Wrap(queryTypeDiscriminator);
226+
}
227+
228+
[OnDeserialized]
229+
private void OnDeserialized(StreamingContext context)
230+
{
231+
queryTypeDiscriminator = _serializableQueryTypeDiscriminator?.GetSystemType();
232+
}
233+
224234
public override bool Equals(object obj)
225235
{
226236
return this == obj || Equals(obj as HQLQueryPlanKey);

src/NHibernate/Impl/CriteriaImpl.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Runtime.Serialization;
45
using System.Text;
56
using System.Threading;
67
using NHibernate.Criterion;
@@ -17,7 +18,9 @@ namespace NHibernate.Impl
1718
[Serializable]
1819
public partial class CriteriaImpl : ICriteria
1920
{
20-
private readonly System.Type persistentClass;
21+
[NonSerialized]
22+
private System.Type persistentClass;
23+
private SerializableSystemType _serializablePersistentClass;
2124
private readonly List<CriterionEntry> criteria = new List<CriterionEntry>();
2225
private readonly List<OrderEntry> orderEntries = new List<OrderEntry>(10);
2326
private readonly Dictionary<string, FetchMode> fetchModes = new Dictionary<string, FetchMode>();
@@ -72,6 +75,18 @@ public CriteriaImpl(string entityOrClassName, string alias, ISessionImplementor
7275
subcriteriaByAlias[alias] = this;
7376
}
7477

78+
[OnSerializing]
79+
private void OnSerializing(StreamingContext context)
80+
{
81+
_serializablePersistentClass = SerializableSystemType.Wrap(persistentClass);
82+
}
83+
84+
[OnDeserialized]
85+
private void OnDeserialized(StreamingContext context)
86+
{
87+
persistentClass = _serializablePersistentClass?.GetSystemType();
88+
}
89+
7590
public ISessionImplementor Session
7691
{
7792
get { return session; }

src/NHibernate/InstantiationException.cs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
22
using System.Runtime.Serialization;
33
using System.Security;
4-
using System.Security.Permissions;
4+
using NHibernate.Util;
55

66
namespace NHibernate
77
{
@@ -11,15 +11,13 @@ namespace NHibernate
1111
[Serializable]
1212
public class InstantiationException : HibernateException
1313
{
14-
private readonly System.Type type;
14+
[NonSerialized]
15+
private readonly System.Type _type;
1516

1617
public InstantiationException(string message, System.Type type)
1718
: base(message)
1819
{
19-
if (type == null)
20-
throw new ArgumentNullException("type");
21-
22-
this.type = type;
20+
_type = type ?? throw new ArgumentNullException(nameof(type));
2321
}
2422

2523
/// <summary>
@@ -35,19 +33,13 @@ public InstantiationException(string message, System.Type type)
3533
public InstantiationException(string message, Exception innerException, System.Type type)
3634
: base(message, innerException)
3735
{
38-
if (type == null)
39-
throw new ArgumentNullException("type");
40-
41-
this.type = type;
36+
_type = type ?? throw new ArgumentNullException(nameof(type));
4237
}
4338

4439
/// <summary>
4540
/// Gets the <see cref="System.Type"/> that NHibernate was trying to instantiate.
4641
/// </summary>
47-
public System.Type PersistentType
48-
{
49-
get { return type; }
50-
}
42+
public System.Type PersistentType => _type;
5143

5244
/// <summary>
5345
/// Gets a message that describes the current <see cref="InstantiationException"/>.
@@ -56,10 +48,7 @@ public System.Type PersistentType
5648
/// The error message that explains the reason for this exception and the Type that
5749
/// was trying to be instantiated.
5850
/// </value>
59-
public override string Message
60-
{
61-
get { return base.Message + (type == null ? "" : type.FullName); }
62-
}
51+
public override string Message => base.Message + (_type == null ? "" : _type.FullName);
6352

6453
#region ISerializable Members
6554

@@ -76,7 +65,7 @@ public override string Message
7665
/// </param>
7766
protected InstantiationException(SerializationInfo info, StreamingContext context) : base(info, context)
7867
{
79-
this.type = info.GetValue("type", typeof(System.Type)) as System.Type;
68+
_type = info.GetValue<System.Type>("type");
8069
}
8170

8271
/// <summary>
@@ -94,7 +83,7 @@ protected InstantiationException(SerializationInfo info, StreamingContext contex
9483
public override void GetObjectData(SerializationInfo info, StreamingContext context)
9584
{
9685
base.GetObjectData(info, context);
97-
info.AddValue("type", type, typeof(System.Type));
86+
info.AddValue("type", ObjectReferenceSystemType.Wrap(_type, true));
9887
}
9988

10089
#endregion

src/NHibernate/Intercept/AbstractFieldInterceptor.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Runtime.Serialization;
34
using NHibernate.Engine;
45
using NHibernate.Proxy;
6+
using NHibernate.Util;
57

68
namespace NHibernate.Intercept
79
{
@@ -16,7 +18,9 @@ public abstract class AbstractFieldInterceptor : IFieldInterceptor
1618
private readonly ISet<string> unwrapProxyFieldNames;
1719
private readonly HashSet<string> loadedUnwrapProxyFieldNames = new HashSet<string>();
1820
private readonly string entityName;
19-
private readonly System.Type mappedClass;
21+
[NonSerialized]
22+
private System.Type mappedClass;
23+
private SerializableSystemType _serializableMappedClass;
2024

2125
[NonSerialized]
2226
private bool initializing;
@@ -31,6 +35,18 @@ protected internal AbstractFieldInterceptor(ISessionImplementor session, ISet<st
3135
this.mappedClass = mappedClass;
3236
}
3337

38+
[OnSerializing]
39+
private void OnSerializing(StreamingContext context)
40+
{
41+
_serializableMappedClass = SerializableSystemType.Wrap(mappedClass);
42+
}
43+
44+
[OnDeserialized]
45+
private void OnDeserialized(StreamingContext context)
46+
{
47+
mappedClass = _serializableMappedClass?.GetSystemType();
48+
}
49+
3450
#region IFieldInterceptor Members
3551

3652
public bool IsDirty

src/NHibernate/Mapping/Array.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ namespace NHibernate.Mapping
1010
[Serializable]
1111
public class Array : List
1212
{
13+
[NonSerialized]
1314
private System.Type elementClass;
15+
1416
private string elementClassName;
1517

1618
public Array(PersistentClass owner) : base(owner)
@@ -21,23 +23,22 @@ public System.Type ElementClass
2123
{
2224
get
2325
{
24-
if (elementClass == null)
26+
if (elementClass != null) return elementClass;
27+
28+
if (elementClassName == null)
29+
{
30+
IType elementType = Element.Type;
31+
elementClass = IsPrimitiveArray ? ((PrimitiveType) elementType).PrimitiveClass : elementType.ReturnedClass;
32+
}
33+
else
2534
{
26-
if (elementClassName == null)
35+
try
2736
{
28-
IType elementType = Element.Type;
29-
elementClass = IsPrimitiveArray ? ((PrimitiveType) elementType).PrimitiveClass : elementType.ReturnedClass;
37+
elementClass = ReflectHelper.ClassForName(elementClassName);
3038
}
31-
else
39+
catch (Exception cnfe)
3240
{
33-
try
34-
{
35-
elementClass = ReflectHelper.ClassForName(elementClassName);
36-
}
37-
catch (Exception cnfe)
38-
{
39-
throw new MappingException(cnfe);
40-
}
41+
throw new MappingException(cnfe);
4142
}
4243
}
4344
return elementClass;
@@ -68,4 +69,4 @@ public string ElementClassName
6869
}
6970
}
7071
}
71-
}
72+
}

0 commit comments

Comments
 (0)