ubeac / ubeac-api

Source of uBeac .NET Core packages
3 stars 2 forks source link

Fix Bson Serialization Issue šŸ™‚ #95

Closed ilhesam closed 2 years ago

ilhesam commented 2 years ago

I was able to find a good solution to solve the json serialization issue šŸ˜€ In this solution, we do not need to store type of application context in other classes.

ā“ What is the solution? In fact, instead of registering serializers in the startup, I register them in mongodb context, But in a very clean form :)) I am registering a class called BsonSerializationOptions with MongoDBContext:

public static IServiceCollection AddMongo<TMongoDbContext>(this IServiceCollection services, string connectionString, bool dropExistDatabase = false)
       where TMongoDbContext : class, IMongoDBContext
    {
        // Other Code

        services.AddSingleton(provider =>
        {
            var appContextType = provider.CreateScope().ServiceProvider.GetRequiredService<IApplicationContext>().GetType();

            return new BsonSerializationOptions
            {
                Serializers = new Dictionary<Type, IBsonSerializer>
                {
                    { typeof(Guid), new GuidSerializer(GuidRepresentation.Standard) },
                    { typeof(decimal), new DecimalSerializer(BsonType.Decimal128) },
                    { typeof(decimal?), new NullableSerializer<decimal>(new DecimalSerializer(BsonType.Decimal128)) },
                    { typeof(IApplicationContext), new AppContextBsonSerializer(appContextType) }
                },
                GuidRepresentationMode = GuidRepresentationMode.V3
            };
        });

        return services;
    }

And then in MongoDBContext, I configure it:

public MongoDBContext(MongoDBOptions dbOptions, BsonSerializationOptions bsonSerializationOptions)
    {
        ConfigureBsonSerialization(bsonSerializationOptions);
        ConfigureDatabase(dbOptions);
    }

private void ConfigureBsonSerialization(BsonSerializationOptions options)
    {
        BsonDefaults.GuidRepresentationMode = options.GuidRepresentationMode;

        try
        {
            if (options.Serializers?.Any() == true)
                foreach (var (type, serializer) in options.Serializers)
                    if (BsonSerializer.LookupSerializer(type) == null)
                        BsonSerializer.RegisterSerializer(type, serializer);
        }
        catch
        {
            // ignored
        }
    }

I'm really a genius šŸ˜Ž