MongoGogo 3.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package MongoGogo --version 3.1.0                
NuGet\Install-Package MongoGogo -Version 3.1.0                
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="MongoGogo" Version="3.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add MongoGogo --version 3.1.0                
#r "nuget: MongoGogo, 3.1.0"                
#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 MongoGogo as a Cake Addin
#addin nuget:?package=MongoGogo&version=3.1.0

// Install MongoGogo as a Cake Tool
#tool nuget:?package=MongoGogo&version=3.1.0                

MongoGogo Guide

MongoGogo is a generic repository implementation based on ORM-like (Object-Relational Mapping) technology, aimed at helping developers effortlessly interact with databases in their applications. This package is designed to simplify database access, provide a more convenient API, and separate business logic from the details of data storage.

I hope this translation is helpful. If you have any further questions, please feel free to ask.

Key Features

  • An ORM-like implementation using MongoDB.Driver, which simplifies database interactions.
  • Automatic implementation of dependency injection for Microsoft.Extensions.DependencyInjection, streamlining the setup process.
  • Provides attributes for managing databases and collections for each connection, allowing for easy configuration and customization.
  • Each interface is a unique implementation, with the distinction between different interfaces determined by their respective types.

Install via .NET CLI

dotnet add package MongoGogo 

Example

  • After few steps of configuration and class building(introduced later), you can easily get your Collection in abstract through the dependency resolution system.
public class MyController : ControllerBase
{
    private readonly IGoCollection<Hospital> HospitalRepository;

    public MyController(IGoCollection<Hospital> hospitalRepository)
    {
      this.HospitalRepository = hospitalRepository;
    }
}
  • Easily access data.
public class MyController : ControllerBase
{
    [HttpGet("IGoCollection<Hospital>_GetList")]
    public async Task<IActionResult> Hospitals()
    {
        var hospitals = await HospitalRepository.FindAsync(_ => true);
        return Ok(hospitals);
    }
}
  • Additionally, MongoGogo provides abstract access to any Collection, Database, and context!
public class MyController : ControllerBase
{
    private readonly IGoContext<MyMongoDBContext> MyContext;
    private readonly IGoDatabase<MyMongoDBContext.City> CityDatabase;
    private readonly IGoCollection<Hospital> HospitalCollection;

    public MyController(IGoContext<MyMongoDBContext> myContext,
                        IGoDatabase<MyMongoDBContext.City> cityDatabase,
                        IGoCollection<Hospital> hospitalCollection)
    {
        this.MyContext = myContext;
        this.CityDatabase = cityDatabase;
        this.HospitalCollection = hospitalCollection;
    }
}

IGoContext<T>IGoDatabase<T> and IGoCollection<T>:

  • Are of generic type with very few restrictions
  • Act like IMongoClient, IMongoDatabase, and IMongoCollection<T> from the well-known package MongoDB.Driver.
using MongoDB.Driver;
public class MyController : ControllerBase
{
    [HttpGet("IGoCollection<T>_GetList")]
    public async Task<IActionResult> Collection()
    {
        var hospitals = (await HospitalCollection.FindAsync(_ => true)).ToEnumerable();
        return Ok(hospitals);
    }

    [HttpGet("IGoDatabase<T>_ListAllCollections")]
    public IActionResult Database()
    {
        var collectionNames = CityDatabase.ListCollectionNames().ToList();
        return Ok(collectionNames);
    }

    [HttpGet("IGoContext_DeleteDatabasebyName")]
    public IActionResult Context(string databaseName)
    {
        MyContext.DropDatabase(databaseName);
        return Ok($"{databaseName} is successfully droped.");
    }
}

Configuration

In the ConfigureSerivces segment of .net core, pass an IGoContext instance into your IServiceCollection.

The build of concrete class MyMongoDBContext is introduced next part.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMongoContext(new MyMongoDBContext("my mongodb connection string"));
}

Alternatively, you can configure the mongoContext through an implementationFactory.

public void ConfigureServices(IServiceCollection services)
{
    Func<IServiceProvider, object> implementationFactory; //some custom factory
    services.AddMongoContext<MyMongoDBContext>(implementationFactory);
}

  • LifeCycleOption: Singleton, Scoped, Transient

In addition, you can control the lifecycle of all IGoContext<T>, IGoDatabase<T>, IGoCollection<T>, and IMongoCollection<T> using LifeCycleOption. The default is Scoped.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMongoContext(new MyMongoDBContext("my mongodb connection string"),
                 new LifeCycleOption
                                 {
                                     ContextLifeCycle = LifeCycleType.Singleton,
                                     DatabaseLifeCycle = LifeCycleType.Scoped,
                   GoCollectionLifeCycle = LifeCycleType.Transient,
                                     MongoCollectionLifeCycle = LifeCycleType.Scoped
                                 });
}

Core Components: [Context], [Database], and [Collections]

[Context] And [Database]

IGoContext<TContext>
  • Represents a MongoDB Connection (using the MongoDB.Driver package)
  • An instance stores the connection string and is responsible for the structure of an entity.
  • The generic TContext, which refers to the type itself, is used for the dependency resolution system.
public class MyMongoDBContext : GoContext<MyMongoDBContext>
{
    [MongoDatabase]
    public class City { }

    [MongoDatabase("Log")]
    public class Logger { }

    [MongoDatabase]
    public class Admin { }
    
    public MyMongoDBContext(string connectionString) : base(connectionString)
    {
    }
}
public abstract class GoContext<TContext> : IGoContext<TContext> 
{
    //...
}

Congratulations! You have successfully set up the database in the IGoContext.

A vaild database of an entity/context must be:

  • An inner class of IGoContext<TContext> which is public or internal

  • Decorated with the MongoDatabase attribute

[Collections]

Assuming the City database has two collections, City and Hospital:

  • Decorated with the MongoCollection attribute, and specify the corresponding database type.
  • Note that this database type must be an inner class of an IGoContext<TContext>
// 'City' Collection
[MongoCollection(fromDatabase: typeof(MyMongoDBContext.City))]
public class City
{
    [BsonId]
    public ObjectId _id { get; set; }

    public string Name { get; set; }

    public int Population { get; set; }
}

Alternatively, you can use the attribute of MongoDB.Driver if you have some restrictions on this collection, field, or even some Serializer.

using MongoDB.Bson.Serialization.Attributes;

// 'Hospital' Collection
[MongoCollection(typeof(MyMongoDBContext.City),"Hospital"]
[BsonIgnoreExtraElements]
public class Hospital
{
    [BsonId]
    public ObjectId _id { get; set; }

    [BsonElement("FullName")]
    public string Name { get; set; }

    [BsonIgnoreIfDefault]
    public City City { get; set; }
}

By default, resolution system will build exactly one IGoCollection<TDocument> for every TDocument decorated by [MongoCollection] .

IGoCollection<TDocument> is responsible for the connection between a MongoDB connection and your project.

public class MyClass
{
    private readonly IGoCollection<Hospital> HospitalGoCollection;
  private readonly IMongoCollection<Hospital> HospitalMongoCollection;

    public MyClass(IGoCollection<Hospital> hospitalGoCollection,
               IMongoCollection<Hospital> hospitalMongoCollection)
    {
        this.HospitalGoCollection = hospitalGoCollection;        
        this.HospitalMongoCollection = hospitalMongoCollection;
    }
}

In fact, you can work with data using either IGoCollection<Hospital> or IMongoCollection<Hospital>.

The main differences between them are:

  • IGoCollection<Hospital> is a packaged instance, but with handy methods to operate on your data.
  • IMongoCollection<Hospital> is the instance from MongoDB.Driver
public async Task AddNewHospital(Hospital hospital)
{
    HospitalCollection.InsertOne(hospital);
    HospitalMongoCollection.InsertOne(hospital);
}
  • IGoCollection<Tdocument> has basic method dealing your data, like FindOneAsync, InsertOne, ReplaceOne, Count, and so on.
  • If you want to add extra features, you can do it yourself by overriding the original methods!
Custom [Collection]

If the basic functionality of IGoCollection<TDocument> does not meet your needs,

(for example: printing a message and saving it as a local log)

you can inherit GoCollectionAbstract<TDocument> and create your own child class.

public class MyCustomHosipitalCollection : GoCollectionAbstract<Hospital>
{
    //You dont need to worry how to deal with the  IMongoCollection instance here, the resolution system will take it.
    public HospitalRepository(IMongoCollection<Hospital> collection) : base(collection)
    {
    }
    
    //write your own code here.
    public override void InsertOne(Hospital hospital)
    {
        base.InsertOne(hospital);
        Logger.PrintAndSave(hospital); //print insert success and save
    }
}

After this, the resolution system will map the new child class MyCustomHosipitalCollection to IGoCollection<Hospital>.

public class MyClass
{
  private readonly IGoCollection<Hospital> HospitalGoCollection; //actually your new class HospitalRepository
    private readonly IMongoCollection<Hospital> HospitalMongoCollection; //not changed
  

    public MyClass(IGoCollection<Hospital> hospitalGoCollection,
             IMongoCollection<Hospital> hospitalMongoCollection)
    {
        this.HospitalGoCollection = hospitalGoCollection; //actually your new class HospitalRepository
        this.HospitalMongoCollection = hospitalMongoCollection; //not changed
    }
    
    public async Task AddNewHospital(Hospital hospital)
    {
        HospitalGoCollection.InsertOne(hospital);  // it will print insert success and save

        HospitalMongoCollection.InsertOne(hospital);  // nothing else
    }
}
  • By customizing and extending the functionality provided by the package, you can tailor your solution to your specific needs while still leveraging the powerful features and ease of use provided by the package.

IGoCollection Methods

This section showcases the basic methods of IGoCollection<TDocument>.

IGoCollection<City> CityCollection;

Count / CountAsync

var documentCount = CityCollection.Count(city => city.Population >= 1000);
var documentCountAsync = await CityCollection.CountAsync(city => city.Population >= 1000);

Find/FindAsync

var foundDocuments = CityCollection.Find(city => city.Population >= 1000);
var foundDocumentAsync = await CityCollection.FindAsync(city => city.Population >= 1000);
  • with goFindOption (optional)
var foundDocuments = CityCollection.Find(city => city.Population >= 1000,
                                         goFindOption: new GoFindOption
                                        {
                                            AllowDiskUse = true,
                                            Limit = 2,
                                            Skip = 1
                                        });
var foundDocumentAsync = await CityCollection.FindAsync(city => city.Population >= 1000, 
                                                        goFindOption: new GoFindOption
                                                        {
                                                            AllowDiskUse = true,
                                                            Limit = 2,
                                                            Skip = 1
                                                        });
  • field reduction with projection(optional)
var reducedDocuments = CityCollection.Find(city => city.Population >= 1000,
                                           projection: builder => builder.Include(city => city.Population)
                                                                         .Include(city => city.Name));
var reducedDocumentAsync = await CityCollection.FindAsync(city => city.Population >= 1000, 
                                                          projection: builder => builder.Include(city => city.Population)
                                                                                        .Include(city => city.Name));

FindOne/FindOneAsync

var firstOrDefaultDocument = CityCollection.FindOne(city => city.Population >= 1000);
var firstOrDefaultDocumentAsync = await CityCollection.FindOneAsync(city => city.Population >= 1000);

InsertOne/InsertOneAsync

CityCollection.InsertOne(new City{Name = "New York"});
await CityCollection.InsertOneAsync(new City{Name = "New York"});

InsertMany/InsertManyAsync

var cityList = new List<City>
{
  new City{}, 
  new City{Name = "New York"}, 
  new City{Population = 100}
};

CityCollection.InsertMany(cityList);
await CityCollection.InsertManyAsync(cityList);

ReplaceOne/ReplaceOneAsync

var city = new City
{
  Name = "NewYork_America"
};

CityCollection.ReplaceOne(c => c.Name == "NewYork",
              city);
await CityCollection.ReplaceOneAsync(c => c.Name == "NewYork",
                   city);
  • with upsert(optional)
CityCollection.ReplaceOne(c => c.Name == "NewYork",
                          city,
                          isUpsert: true);
await CityCollection.ReplaceOneAsync(c => c.Name == "NewYork",
                                     city,
                                     isUpsert: true);

UpdateOne/UpdateOneAsync

CityCollection.UpdateOne(city => city.Name == "New York",
                         builder => builder.Set(city => city.Name, "New York_America")
                                   .Set(city => city.Population, 1000));
await CityCollection.UpdateOneAsync(city => city.Name == "New York",
                                    builder => builder.Set(city => city.Name, "New York_America")
                                              .Set(city => city.Population, 1000));
  • with upsert(optional)
CityCollection.UpdateOne(city => city.Name == "New York",
                         builder => builder.Set(city => city.Name, "New York_America")
                                   .Set(city => city.Population, 1000),
                         isUpsert: true);
await CityCollection.UpdateOneAsync(city => city.Name == "New York",
                                    builder => builder.Set(city => city.Name, "New York_America")
                                              .Set(city => city.Population, 1000),
                                   isUpsert: true);

UpdateMany/UpdateManyAsync

CityCollection.UpdateMany(city => city.Name == "New York",
                          builder => builder.Set(city => city.Name, "New York_America")
                                    .Set(city => city.Population, 1000));
await CityCollection.UpdateManyAsync(city => city.Name == "New York",
                                     builder => builder.Set(city => city.Name, "New York_America")
                                               .Set(city => city.Population, 1000));

DeleteOne/DeleteOneAsync

CityCollection.DeleteOne(city => city.Name == "New York");
await CityCollection.DeleteOneAsync(city => city.Name == "New York");

DeleteMany/DeleteManyAsync

CityCollection.DeleteMany(city => city.Name == "New York");
await CityCollection.DeleteManyAsync(city => city.Name == "New York");
Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  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. 
.NET Core netcoreapp3.1 is compatible. 
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
6.0.0 66 5/20/2024
5.4.1 104 2/5/2024
5.4.0 82 2/2/2024
5.3.0 802 11/16/2023
5.2.2 120 11/3/2023
5.2.1 780 8/7/2023
5.2.0 318 7/24/2023
5.1.2 149 7/21/2023
5.1.1 239 7/4/2023
5.0.1 226 6/28/2023
4.0.0 163 6/19/2023
3.1.0 635 3/17/2023
2.0.1 551 11/18/2022
2.0.0 347 11/18/2022
1.0.3 327 11/10/2022
1.0.2 353 11/9/2022
1.0.1 328 11/9/2022
1.0.0 355 11/9/2022