{"id":13601323,"url":"https://github.com/alexandre-spieser/mongodb-generic-repository","last_synced_at":"2026-01-12T09:59:45.063Z","repository":{"id":39635907,"uuid":"52662265","full_name":"alexandre-spieser/mongodb-generic-repository","owner":"alexandre-spieser","description":"An example of generic repository implementation using the MongoDB C# Sharp 2.0 driver (async)","archived":false,"fork":false,"pushed_at":"2024-05-28T14:42:45.000Z","size":40014,"stargazers_count":310,"open_issues_count":8,"forks_count":84,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-08-02T18:40:20.635Z","etag":null,"topics":["generic","mongodb","repository"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexandre-spieser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-02-27T10:51:09.000Z","updated_at":"2024-06-28T10:50:38.000Z","dependencies_parsed_at":"2024-01-12T01:14:38.060Z","dependency_job_id":"5697b207-e56c-43d7-b085-dad77c8af0c1","html_url":"https://github.com/alexandre-spieser/mongodb-generic-repository","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-spieser%2Fmongodb-generic-repository","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-spieser%2Fmongodb-generic-repository/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-spieser%2Fmongodb-generic-repository/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandre-spieser%2Fmongodb-generic-repository/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandre-spieser","download_url":"https://codeload.github.com/alexandre-spieser/mongodb-generic-repository/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223458240,"owners_count":17148441,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["generic","mongodb","repository"],"created_at":"2024-08-01T18:01:00.482Z","updated_at":"2026-01-12T09:59:45.055Z","avatar_url":"https://github.com/alexandre-spieser.png","language":"C#","funding_links":["https://www.buymeacoffee.com/zeitquest"],"categories":["C# #","Libraries"],"sub_categories":["MongoDb"],"readme":"# MongoDbGenericRepository\n\nAn example of generic repository implementation using the MongoDB C# Sharp 2.0 (and now 3.*) driver (async)\n\nNow available as a nuget package:\nhttps://www.nuget.org/packages/MongoDbGenericRepository/\n\nCovered by 400+ integration tests and counting.\n\nThe MongoDbGenericRepository is also used in [AspNetCore.Identity.MongoDbCore](https://github.com/alexandre-spieser/AspNetCore.Identity.MongoDbCore).\n\n# Support This Project\n\nIf you have found this project helpful, either as a library that you use or as a learning tool, please consider buying Alex a coffee: \u003ca href=\"https://www.buymeacoffee.com/zeitquest\" target=\"_blank\"\u003e\u003cimg height=\"40px\" src=\"https://cdn.buymeacoffee.com/buttons/default-orange.png\" alt=\"Buy Me A Coffee\" style=\"max-height: 51px;width: 150px !important;\" \u003e\u003c/a\u003e\n\n# Worth Knowing\n\nThis package sets the `MongoDefaults.GuidRepresentation` to `MongoDB.Bson.GuidRepresentation.Standard` by default, instead of the default driver setting of `MongoDB.Bson.GuidRepresentation.CSharpLegacy`. This can cause issues if you have been using the driver on an existing application previously or if you are using CosmosDB.\n\nYou can override this behaviour to enforce legacy behaviour in your app Startup routine like so :\n\n`MongoDbContext.SetGuidRepresentation(MongoDB.Bson.GuidRepresentation.CSharpLegacy)`. More info [here](https://github.com/alexandre-spieser/mongodb-generic-repository/issues/7).\n\n# Usage examples\n\nThis repository is meant to be inherited from. \n\nYou are responsible for managing its lifetime, it is advised to setup this repository as a singleton.\n\nHere is an example of repository usage, where the TestRepository is implementing 2 custom methods:\n\n```csharp\n    public interface ITestRepository : IBaseMongoRepository\n    {\n        void DropTestCollection\u003cTDocument\u003e();\n        void DropTestCollection\u003cTDocument\u003e(string partitionKey);\n    }\n    \n    public class TestRepository : BaseMongoRepository, ITestRepository\n    {\n        public TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName)\n        {\n        }\n\n        public void DropTestCollection\u003cTDocument\u003e()\n        {\n            MongoDbContext.DropCollection\u003cTDocument\u003e();\n        }\n\n        public void DropTestCollection\u003cTDocument\u003e(string partitionKey)\n        {\n            MongoDbContext.DropCollection\u003cTDocument\u003e(partitionKey);\n        }\n    }\n```\nIf all your documents have the same type of `Id`, you can use the more specific `BaseMongoRepository\u003cTKey\u003e` where `TKey` is the type of the `Id` of your documents.\n```csharp\n    public class TestTKeyRepository\u003cTKey\u003e : BaseMongoRepository\u003cTKey\u003e, ITestRepository\u003cTKey\u003e where TKey : IEquatable\u003cTKey\u003e\n    {\n        const string connectionString = \"mongodb://localhost:27017/MongoDbTests\";\n        private static readonly ITestRepository\u003cTKey\u003e _instance = new TestTKeyRepository\u003cTKey\u003e(connectionString);\n        /// \u003cinheritdoc /\u003e\n        private TestTKeyRepository(string connectionString) : base(connectionString)\n        {\n        }\n    }\n```\n\n## Instantiation\n\nThe repository can be instantiated like so:\n\n```csharp\nITestRepository testRepository = new TestRepository(connectionString, \"MongoDbTests\");\nITestRepository\u003cTKey\u003e testTKeyRepository = new TestTKeyRepository\u003cTKey\u003e(connectionString);\n```\n\nIf you prefer to reuse the same MongoDb database across your application, you can use the `MongoDatabase` from the MongoDb driver implementing the `IMongoDatabase` interface:\n\n```csharp\nvar client = new MongoClient(connectionString);\nvar mongoDbDatabase = Client.GetDatabase(databaseName);\nITestRepository testRepository = new TestRepository(mongoDbDatabase);\n```\n\n## Adding documents\nTo add a document, its class must inherit from the `Document` class,  implement the `IDocument` or `IDocument\u003cTKey\u003e` interface:\n\n```csharp\n    public class MyDocument : Document\n    {\n        public MyDocument()\n        {\n            Version = 2; // you can bump the version of the document schema if you change it over time\n        }\n        public string SomeContent { get; set; }\n    }\n```\n\nThe `IDocument` and `IDocument\u003cTKey\u003e` interfaces can be seen below:\n\n```csharp\n    /// \u003csummary\u003e\n    /// This class represents a basic document that can be stored in MongoDb.\n    /// Your document must implement this class in order for the MongoDbRepository to handle them.\n    /// \u003c/summary\u003e\n    public interface IDocument\n    {\n        Guid Id { get; set; }\n        int Version { get; set; }\n    }\n    \n    /// \u003csummary\u003e\n    /// This class represents a basic document that can be stored in MongoDb.\n    /// Your document must implement this class in order for the MongoDbRepository to handle them.\n    /// \u003c/summary\u003e\n    public interface IDocument\u003cTKey\u003e where TKey : IEquatable\u003cTKey\u003e\n    {\n        /// \u003csummary\u003e\n        /// The Primary Key, which must be decorated with the [BsonId] attribute \n        /// if you want the MongoDb C# driver to consider it to be the document ID.\n        /// \u003c/summary\u003e\n        [BsonId]\n        TKey Id { get; set; }\n        /// \u003csummary\u003e\n        /// A version number, to indicate the version of the schema.\n        /// \u003c/summary\u003e\n        int Version { get; set; }\n    }\n```\n\n## Partitioned collections\nThis repository also allows you to partition your document across multiple collections, this can be useful if you are running a SaaS application and want to keep good performance.\n\nTo use partitioned collections, you must define your documents using the PartitionedDocument class, which implements the IPartitionedDocument interface:\n```csharp\n    public class MyPartitionedDocument : PartitionedDocument\n    {\n        public MyPartitionedDocument(string myPartitionKey) : base(myPartitionKey)\n        {\n            Version = 1;\n        }\n        public string SomeContent { get; set; }\n    }\n```\n\nThis partitioned key will be used as a prefix to your collection name.\nThe collection name is derived from the name of the type of your document, is set to camel case, and is pluralized using a class taken from Humanizer (https://github.com/Humanizr/Humanizer).\n\n```csharp\nvar myDoc = new MyPartitionedDocument(\"myPartitionKey\");\n_testRepository.AddOne(myDoc);\n```\n\nThe above code will generate a collection named `myPartitionKey-myPartitionedDocuments`.\n\n## CollectionName Attribute\nIt is now possible to change the collection name by using the `CollectionName` attribute:\n\n```csharp\n    [CollectionName(\"MyCollectionName\")]\n    public class MyDocument : Document\n    {\n        public MyDocument()\n        {\n            Version = 2;\n        }\n        public string SomeContent { get; set; }\n    }\n```\nDocuments of this type will be inserted into a collection named \"MyCollectionName\".\n\n## Index Management\nFrom version 1.3.8 the `MongoDbGenericRepository` implements the `IBaseMongoRepository_Index` and  `IBaseMongoRepository_Index\u003cTKey\u003e` interfaces. \nThis exposes the functionality to programmatically manage indexes against your collections in a generic fashion.\n\nThe following methods are exposed and fully integration tested:\n+ CreateAscendingIndexAsync\n+ CreateDescendingIndexAsync\n+ CreateCombinedTextIndexAsync\n+ CreateHashedIndexAsync\n+ CreateTextIndexAsync\n+ DropIndexAsync\n+ GetIndexesNamesAsync\n\nUsage examples:  \n```csharp\n\tstring expectedIndexName = $\"myCustomIndexName\";\n\tvar option = new IndexCreationOptions\n\t{\n\t\tName = expectedIndexName\n\t};\n\t// Act\n\t// create a text index against the Version property of the document.\n\tvar result = await SUT.CreateTextIndexAsync\u003cT, TKey\u003e(x =\u003e x.Version, option, PartitionKey);\n\n\t// Assert\n\tvar listOfIndexNames = await SUT.GetIndexesNamesAsync\u003cT, TKey\u003e(PartitionKey);\n\tAssert.Contains(expectedIndexName, listOfIndexNames);\n\n\t// Cleanup\n\tawait SUT.DropIndexAsync\u003cT, TKey\u003e(expectedIndexName, PartitionKey);\n```\n\nPlease refer to the IntegrationTests (NET45) and CoreIntegrationTests (netstandard2.0) projects for more usage examples.\nThe `CoreIntegrationTests.Infrastructure.MongoDbTKeyDocumentTestBase\u003cT, TKey\u003e` test class is a good start.\n\n## Author\n**Alexandre Spieser**\n\n## License\nmongodb-generic-repository is under MIT license - http://www.opensource.org/licenses/mit-license.php\n\nThe MIT License (MIT)\n\nCopyright (c) 2016-2019 Alexandre Spieser\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n==============================================================================\n\nInflector (https://github.com/srkirkland/Inflector)\nThe MIT License (MIT)\nCopyright (c) 2013 Scott Kirkland\n\n==============================================================================\n\nHumanizer (https://github.com/Humanizr/Humanizer)\nThe MIT License (MIT)\nCopyright (c) 2012-2014 Mehdi Khalili (http://omar.io)\n\n==============================================================================\n\n## Copyright\nCopyright © 2019\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandre-spieser%2Fmongodb-generic-repository","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandre-spieser%2Fmongodb-generic-repository","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandre-spieser%2Fmongodb-generic-repository/lists"}