Tharga.MongoDb 1.9.25

There is a newer version of this package available.
See the version list below for details.
dotnet add package Tharga.MongoDb --version 1.9.25
NuGet\Install-Package Tharga.MongoDb -Version 1.9.25
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tharga.MongoDb" Version="1.9.25" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Tharga.MongoDb --version 1.9.25
#r "nuget: Tharga.MongoDb, 1.9.25"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Tharga.MongoDb as a Cake Addin
#addin nuget:?package=Tharga.MongoDb&version=1.9.25

// Install Tharga.MongoDb as a Cake Tool
#tool nuget:?package=Tharga.MongoDb&version=1.9.25

Tharga.MongoDb

This package was broken out of a product that needs the possibility of dynamic naming of databases and collections. I also helps with structuring what functions are to be accessed for different types.

It also have some aditional features for Atlas MongoDB like limiting the size of the responses and opening the firewall.

Get started

Install the nuget package Tharga.MongoDb.

Register to use

Register this package at startup by calling AddMongoDb as an extension to IServiceCollection.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMongoDb();
}

By default the configuration setting ConnectionStrings:Default is used to get the connection string. Customize by providing DatabaseOptions to AddMongoDb.

Create entities, repositories and collections.

The simplest way is to have the repository implement the collection directly.

public class MySimpleRepo : DiskRepositoryCollectionBase<MyEntity, ObjectId>
{
    public MySimpleRepo(IMongoDbServiceFactory mongoDbServiceFactory)
        : base(mongoDbServiceFactory)
    {
    }
}

public record MyEntity : EntityBase<ObjectId>
{
}

The more complex way that gives more control is to implement one class for the repo and another for the collection. This way you can control what methods repo methods are exposed to consumers. Here implemented with interfaces and the collection made internal.

public interface IMySimpleRepo : IRepository
{
    public Task<MyEntity> GetFirstOrDefaultAsync();
}

public class MySimpleRepo : IMySimpleRepo
{
    private readonly IMySimpleCollection _mySimpleCollection;

    public MySimpleRepo(IMySimpleCollection mySimpleCollection)
    {
        _mySimpleCollection = mySimpleCollection;
    }

    public Task<MyEntity> GetFirstOrDefaultAsync()
    {
        return _mySimpleCollection.GetOneAsync(x => true);
    }
}

public interface IMySimpleCollection : IRepositoryCollection<MyEntity, ObjectId>
{
}

internal class MySimpleCollection : DiskRepositoryCollectionBase<MyEntity, ObjectId>, IMySimpleCollection
{
    public MySimpleCollection(IMongoDbServiceFactory mongoDbServiceFactory)
        : base(mongoDbServiceFactory)
    {
    }

    public Task<MyEntity> GetFirstOrDefaultAsync()
    {
        throw new NotImplementedException();
    }
}

public record MyEntity : EntityBase<ObjectId>
{
}

Simple Console Sample

This is a simple demo for a console application written in .NET 7. The following nuget packages are used.

  • Tharga.MongoDb
  • Microsoft.Extensions.Hosting
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Bson;
using Tharga.MongoDb;
using Tharga.MongoDb.Disk;

var services = new ServiceCollection();
services.AddMongoDb(o => o.ConnectionStringLoader = _ => "mongodb://localhost:27017/SimpleConsoleSample");

var serviceProvider = services.BuildServiceProvider();

var simpleRepo = serviceProvider.GetService<MySimpleRepo>();
await simpleRepo!.AddAsync(new MyEntity());
var oneItem = await simpleRepo.GetOneAsync(x => true);

Console.WriteLine($"Got item with id '{oneItem.Id}' from the database.");

public class MySimpleRepo : DiskRepositoryCollectionBase<MyEntity, ObjectId>
{
    public MySimpleRepo(IMongoDbServiceFactory mongoDbServiceFactory)
        : base(mongoDbServiceFactory)
    {
    }
}

public record MyEntity : EntityBase<ObjectId>
{
}

More details

Configuration

Configuring can be done in appsettings.json or by code. Code is always used first value by value. If using multiple (named) databases, configuration will always use the named version first if there is one and then use the general fallback value. This is the order used, value by value.

  1. Named configuration from code
  2. General configuration from code
  3. Named configuration from IConfiguration
  4. General configuration from IConfiguration
  5. Default values
Example of configuration by appsettings.json.

When the 'Default' database is used, the result limit will be 100, for the 'Other' database the result limit will be 200. If another database is implemented, the fallback of 1000 will be used as result limit.

The 'Default' database will have the firewall opened, if hosted in Atlas MongoDB.

  "ConnectionStrings": {
    "Default": "mongodb://localhost:27017/Tharga{environment}_Sample{part}",
    "Other": "mongodb://localhost:27017/Tharga{environment}_Sample_Other{part}"
  },
  "MongoDb": {
    "Default": {
      "AccessInfo": {
        "PublicKey": "[PublicKey]",
        "PrivateKey": "[PrivateKey]",
        "ClusterId": "[ClusterId]"
      },
      "ResultLimit": 100,
      "AutoClean": true,
      "CleanOnStartup": true,
      "DropEmptyCollections": true
    },
    "Other": {
      "ResultLimit": 200
    },
    "ResultLimit": 1000
    "AutoClean": false,
    "CleanOnStartup": false,
    "DropEmptyCollections": false
  }
Example of configuration by code.

This would be the same configuration as from the example above.

        services.AddMongoDb(o =>
        {
            o.ConnectionStringLoader = name =>
            {
                return (string)name switch
                {
                    "Default" => "mongodb://localhost:27017/Tharga{environment}_Sample{part}",
                    "Other" => "mongodb://localhost:27017/Tharga{environment}_Sample_Other{part}",
                    _ => throw new ArgumentException($"Unknown configuration name '{name}'.")
                };
            };
            o.Configuration = new MongoDbConfigurationTree
            {
                Configurations = new Dictionary<ConfigurationName, MongoDbConfiguration>
                {
                    {
                        "Default", new MongoDbConfiguration
                        {
                            AccessInfo = new MongoDbApiAccess
                            {
                                PublicKey = "[PublicKey]",
                                PrivateKey = "[PrivateKey]",
                                ClusterId = "[ClusterId]"
                            },
                            ResultLimit = 100,
                            AutoClean = true,
                            CleanOnStartup = true,
                            DropEmptyCollections = true
                        }
                    },
                    {
                        "Other", new MongoDbConfiguration
                        {
                            ResultLimit = 200
                        }
                    }
                },
                ResultLimit = 1000,
                AutoClean = false,
                CleanOnStartup = false,
                DropEmptyCollections = false
            };
        });

Customize collections

Properties for classes deriving from RepositoryCollectionBase<,> can be customised directly by overriding the default behaviour of the code or configuration.

By default the name of the collection is the same as the type name of the entity. To have a different name the property CollectionName can be overridden.

The name of the database can be built up dynamically, use DatabasePart to do so. Read more about this in the section MongoUrl Builder.

Override property ConfigurationName to use different database than default (or set as default in DatabaseOptions). This makes it possible to use multiple databases from the same application.

The properties AutoClean, CleanOnStartup, DropEmptyCollections and ResultLimit can be overridden by collection to be different from the configuration.

To automatically register known types when using multiple types in the same collection, provide a value for Types.

Create Indicies by overriding the property in your collection class. The list of Indicies is applied befor the first record is added to the collection. It is also reviewed once every time the application starts, removing Indicies that no longer exists and creates new ones if the code have changed.

MongoUrl Builder

The MongoUrl is created by a built in implementation of IMongoUrlBuilder. It takes the raw version and parses variables to build MongoUrl.

Two variables are supported {environment} and {part}.

To dynamicaly change the name of the database {part} can be used. It can be used as an override to a collection or provided as a variable in DatabaseContext together with CollectionProvider.

For {environment} the value will be ommitted when it is set to 'Production'.

Both variables will get a leading character of '_'.

Example for Development with the databasePart = MyPart. mongodb://localhost:27017/Tharga{environment}_Sample{part} --> mongodb://localhost:27017/Tharga_Development_Sample_MyPart

Custom MongoUrl Builder

If there is a need for a custom string builder, implement the interface IMongoUrlBuilder and register with the IOC and that will be used instead of the built in version. Register your own version of IMongoUrlBuilder in IOC.

services.AddTransient<IMongoUrlBuilder, MyMongoUrlBuilder>();

MongoDB Result Limit

It is possible to se t a hard limit for the number of documents returned. If the limit is reached ResultLimitException is thrown. For large result-sets, use the method GetPageAsync to get the ResultLimit on each page of the result.

{
  "MongoDb": {
    "ResultLimit": 500
  }
}
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.11.12 98 4/14/2024
1.11.11 65 4/14/2024
1.11.10 220 3/2/2024
1.11.9 170 2/26/2024
1.11.8 241 2/9/2024
1.11.7 240 2/5/2024
1.11.6 241 2/4/2024
1.11.5 373 1/9/2024
1.11.4 335 1/9/2024
1.11.2 419 12/16/2023
1.11.1 454 12/3/2023
1.10.39 429 11/21/2023
1.10.38 486 10/14/2023
1.10.37 508 10/1/2023
1.10.36 504 10/1/2023
1.10.35 479 10/1/2023
1.10.34 491 9/30/2023
1.10.33 473 9/30/2023
1.10.30 470 9/28/2023
1.10.25 526 9/25/2023
1.10.24 493 9/23/2023
1.10.23 502 9/23/2023
1.10.19 563 8/27/2023
1.10.14 661 7/31/2023
1.10.13 601 7/26/2023
1.10.12 610 7/25/2023
1.10.11 615 7/20/2023
1.10.10 642 7/19/2023
1.10.9 615 7/18/2023
1.10.7 600 7/17/2023
1.10.6 641 7/14/2023
1.10.3 616 7/14/2023
1.10.2 629 7/12/2023
1.9.27 604 7/10/2023
1.9.26 587 7/10/2023
1.9.25 564 7/10/2023
1.9.19 597 7/7/2023
1.9.18 559 7/6/2023
1.9.17 606 7/4/2023
1.9.13 615 7/3/2023
1.9.12 573 7/3/2023
1.9.11 606 5/20/2023
1.9.10 600 5/19/2023
1.9.9 611 5/18/2023
1.9.8 597 5/18/2023
1.9.7 621 5/18/2023
1.9.6 613 5/18/2023
1.9.5 573 5/18/2023
1.9.4 630 5/16/2023
1.9.3 568 5/15/2023
1.9.2 596 5/14/2023
1.8.19 539 5/11/2023
1.8.17 639 4/5/2023
1.8.16 693 3/23/2023
1.8.15 741 12/23/2022
1.8.13 770 12/11/2022
1.8.12 738 12/9/2022
1.8.11 724 11/28/2022
1.8.10 733 11/28/2022
1.8.9 788 11/12/2022
1.8.8 828 11/3/2022
1.8.7 797 11/1/2022
1.8.6 798 11/1/2022
1.8.5 758 11/1/2022
1.8.4 797 10/30/2022
1.8.3 768 10/30/2022
1.7.10 822 9/20/2022
1.7.5 762 11/29/2021
1.7.4 762 11/28/2021
1.6.203 810 9/9/2021
1.6.202 750 9/8/2021
1.6.192 790 7/15/2021
1.6.167 795 5/23/2021
1.6.166 765 5/23/2021
1.6.164 774 5/23/2021
1.6.163 886 3/13/2021
1.6.159 809 2/21/2021
1.6.157 805 2/19/2021
1.6.156 791 2/19/2021
1.6.153 776 2/18/2021
1.0.127 809 1/16/2021