Lds.Bot.Library.Mongo 1.1.0
Bot.Library.Mongo
MongoDB storage for Lds.Bot.Library, which this package brings with it. That package's
readme.md is the manual for the engine itself, and AGENTS.md beside it is the short version — both
are in its own package folder, ~/.nuget/packages/lds.bot.library/<version>/.
The engine takes no database dependency at all. It reaches persistence through three ports —
IConversationStore, IBotUserStore and IBotSettingsStore — and this package implements them over
MongoDB.Driver. Take it if MongoDB is what you have; write your own four registrations if it is not,
and the engine neither knows nor cares.
var database = new MongoClient(connectionString).GetDatabase("mydatabase");
builder.Services.AddBotEngine(client, options => { … }, dialogs => …);
builder.Services.AddBotMongoStores(database); // this package
var app = builder.Build();
await database.EnsureBotIndexesAsync(app.Services.GetRequiredService<BotOptions>());
await app.Services.LoadBotSettingsAsync();
Three collections, in your database on your connection: BotUserInfo,
BotConversationState, BotSettings.
Both startup calls are yours to make, and the order matters. AddBotMongoStores only registers;
it opens nothing. EnsureBotIndexesAsync declares the indexes — including the retention TTL — and
LoadBotSettingsAsync reads the stored settings over the ones configured in code. Call them after the
container is built and before the first update is dispatched. The library owns no background work,
so nothing does this for you.
Retention, and the one setting that is not runtime-changeable
BotOptions.ConversationRetention becomes a TTL index on BotConversationState, so old
conversations are removed by MongoDB rather than by any code here. Two consequences worth knowing:
- It is applied by
EnsureBotIndexesAsync, not byLoadBotSettingsAsync. Changing it therefore needs a deployment — unlikeDialogTimeoutandPurgeUsersIdleFor, which the settings store owns and which take effect without one. That asymmetry is deliberate: a TTL window is an index definition, not a value. - A shortened window deletes on the next index pass, retroactively. There is no grace period.
Purging users is separate and is never automatic: it is IBotAdministration.PurgeUsersAsync, which
your host calls on whatever schedule it likes. See the core package's readme, §7.
Before you upgrade an existing database
Two one-off migrations live in BotMaintenance, and neither runs by itself:
| When | If you skip it | |
|---|---|---|
MigrateBotTrashedFieldAsync() |
Any database written before 2026-08-05 | The user record's trash stamp moved from Deleted to Trashed. The class maps tolerate unknown elements — they have to — so an unmigrated stamp is silently ignored: every trashed account reads back as active and the purge's clock restarts. There is no error to notice. Idempotent, and worth running even if you believe nothing was ever trashed |
BackfillBotTimestampsAsync() |
Before enabling BotOptions.ConversationRetention on a database that predates store-level timestamping |
Those documents carry 0001-01-01, which every TTL window is already past — the index would empty the collection |
What a store has to promise
Nine contracts the engine relies on and cannot check. They are documented in the core package's
readme and they are executable: Bot.Library.Tests/Contracts/ holds one abstract fixture each,
phrased against the port interfaces alone. This package subclasses all nine against a real mongod.
If you write your own store, subclass them too — it is the cheapest way to find out whether it works.
Two things about the stored shape, both measured rather than reasoned, and both preserved here
deliberately: _id is not the same BSON type on all three collections (BotConversationState._id
is an ObjectId, the other two are strings), and the class maps set IgnoreExtraElements, without
which any document written by another version of this package throws on read.
Full documentation: the core package's readme, §7 Persistence.
No packages depend on Lds.Bot.Library.Mongo.
First package release.
UPGRADING AN EXISTING DATABASE: run BotMaintenance.MigrateBotTrashedFieldAsync() once. The user
record's trash stamp moved from `Deleted` to `Trashed`, and an unmigrated stamp is silently
ignored — every trashed account reads back as active, with no error to notice. Idempotent, and
worth running even if you believe nothing was ever trashed.
.NET 10.0
- Lds.Bot.Library (>= 1.1.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
- MongoDB.Driver (>= 3.10.0)
| Version | Downloads | Last updated |
|---|---|---|
| 1.1.1 | 12 | 8/6/2026 |
| 1.1.0 | 69 | 8/6/2026 |
| 1.0.0-preview.2 | 6 | 8/6/2026 |
| 1.0.0-preview.1 | 4 | 8/5/2026 |