@@ -55,9 +55,11 @@ private static IBsonSerializer<TInterface> CreateInterfaceSerializer(IBsonSerial
5555
5656 // private fields
5757 private readonly Type _interfaceType ;
58- private readonly IDiscriminatorConvention _discriminatorConvention ;
5958 private readonly IBsonSerializer < TInterface > _interfaceSerializer ;
60- private readonly IBsonSerializer < object > _objectSerializer ;
59+ private readonly Lazy < IDiscriminatorConvention > _discriminatorConvention ;
60+ private readonly Lazy < IBsonSerializer < object > > _objectSerializer ;
61+
62+ private IBsonSerializationDomain _serializationDomain ;
6163
6264 // constructors
6365 /// <summary>
@@ -109,26 +111,13 @@ public DiscriminatedInterfaceSerializer(IDiscriminatorConvention discriminatorCo
109111 }
110112
111113 _interfaceType = typeof ( TInterface ) ;
112- _discriminatorConvention = discriminatorConvention ?? interfaceSerializer . GetDiscriminatorConvention ( ) ; //QUESTION What do we do here? We don't have the domain close by, should we lazy initialize it during serialization/deserialization?
114+ _discriminatorConvention = discriminatorConvention != null
115+ ? new Lazy < IDiscriminatorConvention > ( ( ) => discriminatorConvention )
116+ : new Lazy < IDiscriminatorConvention > ( ( ) => GetDiscriminatorConvention ( _serializationDomain ) ) ;
117+ _objectSerializer = objectSerializer != null
118+ ? new Lazy < IBsonSerializer < object > > ( ( ) => objectSerializer )
119+ : new Lazy < IBsonSerializer < object > > ( ( ) => GetObjectSerializer ( _serializationDomain ) ) ;
113120 _interfaceSerializer = interfaceSerializer ;
114-
115- if ( objectSerializer == null )
116- {
117- objectSerializer = BsonSerializer . LookupSerializer < object > ( ) ; //QUESTION What do we do here? We don't have the domain close by, should we lazy initialize it during serialization/deserialization?
118- if ( objectSerializer is ObjectSerializer standardObjectSerializer )
119- {
120- Func < Type , bool > allowedTypes = ( Type type ) => typeof ( TInterface ) . IsAssignableFrom ( type ) ;
121- objectSerializer = standardObjectSerializer
122- . WithDiscriminatorConvention ( _discriminatorConvention )
123- . WithAllowedTypes ( allowedTypes , allowedTypes ) ;
124- }
125- else
126- {
127- throw new BsonSerializationException ( "Can't set discriminator convention on custom object serializer." ) ;
128- }
129- }
130-
131- _objectSerializer = objectSerializer ;
132121 }
133122
134123 // public properties
@@ -149,6 +138,7 @@ public DiscriminatedInterfaceSerializer(IDiscriminatorConvention discriminatorCo
149138 /// <exception cref="System.FormatException"></exception>
150139 public override TInterface Deserialize ( BsonDeserializationContext context , BsonDeserializationArgs args )
151140 {
141+ _serializationDomain = context . SerializationDomain ;
152142 var bsonReader = context . Reader ;
153143
154144 if ( bsonReader . GetCurrentBsonType ( ) == BsonType . Null )
@@ -158,7 +148,7 @@ public override TInterface Deserialize(BsonDeserializationContext context, BsonD
158148 }
159149 else
160150 {
161- var actualType = _discriminatorConvention . GetActualTypeInternal ( bsonReader , typeof ( TInterface ) , context . SerializationDomain ) ;
151+ var actualType = _discriminatorConvention . Value . GetActualTypeInternal ( bsonReader , typeof ( TInterface ) , context . SerializationDomain ) ;
162152 if ( actualType == _interfaceType )
163153 {
164154 var message = string . Format ( "Unable to determine actual type of object to deserialize for interface type {0}." , _interfaceType . FullName ) ;
@@ -193,6 +183,7 @@ obj is DiscriminatedInterfaceSerializer<TInterface> other &&
193183 /// <param name="value">The document.</param>
194184 public override void Serialize ( BsonSerializationContext context , BsonSerializationArgs args , TInterface value )
195185 {
186+ _serializationDomain = context . SerializationDomain ;
196187 var bsonWriter = context . Writer ;
197188
198189 if ( value == null )
@@ -202,7 +193,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
202193 else
203194 {
204195 args . NominalType = typeof ( object ) ;
205- _objectSerializer . Serialize ( context , args , value ) ;
196+ _objectSerializer . Value . Serialize ( context , args , value ) ;
206197 }
207198 }
208199
@@ -217,5 +208,28 @@ public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializati
217208 serializationInfo = null ;
218209 return false ;
219210 }
211+
212+ private IDiscriminatorConvention GetDiscriminatorConvention ( IBsonSerializationDomain serializationDomain )
213+ {
214+ return _interfaceSerializer . GetDiscriminatorConvention ( serializationDomain ) ;
215+ }
216+
217+ private IBsonSerializer < object > GetObjectSerializer ( IBsonSerializationDomain serializationDomain )
218+ {
219+ var objectSerializer = serializationDomain . LookupSerializer < object > ( ) ;
220+ if ( objectSerializer is ObjectSerializer standardObjectSerializer )
221+ {
222+ var allowedTypes = ( Type type ) => typeof ( TInterface ) . IsAssignableFrom ( type ) ;
223+ objectSerializer = standardObjectSerializer
224+ . WithDiscriminatorConvention ( _discriminatorConvention . Value )
225+ . WithAllowedTypes ( allowedTypes , allowedTypes ) ;
226+ }
227+ else
228+ {
229+ throw new BsonSerializationException ( "Can't set discriminator convention on custom object serializer." ) ;
230+ }
231+
232+ return objectSerializer ;
233+ }
220234 }
221235}
0 commit comments