using Elsa.Features.Abstractions; using Elsa.Features.Services; using Elsa.MongoDB.Options; using Elsa.MongoDb.Serializers; using Elsa.Workflows.Core.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using MongoDB.Bson.Serialization; using MongoDB.Driver; using MongoDB.Driver.Core.Extensions.DiagnosticSources; namespace Elsa.MongoDb.Features; /// /// Configures MongoDb. /// public class MongoDbFeature : FeatureBase { /// public MongoDbFeature(IModule module) : base(module) { } /// /// The MongoDB connection string. /// public string ConnectionString { get; set; } /// /// A delegate that configures MongoDb. /// public Action Options { get; set; } = _ => { }; /// public override void Apply() { Services.Configure(Options); Services.AddSingleton(sp => CreateDatabase(sp, ConnectionString)); RegisterSerializers(); Services.AddHealthChecks(); } private void RegisterSerializers() { BsonSerializer.RegisterSerializer(typeof(object), new PolymorphicSerializer()); BsonSerializer.RegisterSerializer(typeof(Type), new TypeSerializer()); BsonSerializer.RegisterSerializer(typeof(Variable), new VariableSerializer()); } private static IMongoDatabase CreateDatabase(IServiceProvider sp, string connectionString) { var options = sp.GetRequiredService>().Value; var mongoUrl = new MongoUrl(connectionString); var settings = MongoClientSettings.FromUrl(mongoUrl); settings.ClusterConfigurator = cb => cb.Subscribe(new DiagnosticsActivityEventSubscriber()); settings.ApplicationName = GetApplicationName(settings); settings.WriteConcern = options.WriteConcern; settings.ReadConcern = options.ReadConcern; settings.ReadPreference = options.ReadPreference; settings.RetryReads = options.RetryReads; settings.RetryWrites = options.RetryWrites; settings.SslSettings = options.SslSettings; var mongoClient = new MongoClient(settings); return mongoClient.GetDatabase(mongoUrl.DatabaseName); } private static string GetApplicationName(MongoClientSettings settings) => string.IsNullOrWhiteSpace(settings.ApplicationName) ? "elsa_workflows" : settings.ApplicationName; }