前几天在网上想找一下Asp.Net Core使用MongoDB相关的文章,也看了几篇,发现都是在写简单的例子,这样的例子是不能用在生产环境的,不能用的生产环境的。封装一个东西一定是建立在你对这个东西足够了解的前提下完成,最起码官方的文档你要看吧。
1、MongoClient 和 MongoDatabase 这两个对象的生命周期怎么处理?
2、每次插入一个document都要动态获取一个Collection吗?
先看一下官方给出的这篇文章:
https://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/
看完这篇文档我们发现MongoClient、MongoDatabase和MongoCollection都是可以重用的,而且是线程安全的。核心代码:
public class MongoRepository<T> where T : class, new()
{
// https://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/#re-use
private readonly MongoOptions _options;
private static IMongoClient _mongoClient;
private static IMongoDatabase _mongoDatabase;
private static object _obj = new object();
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IMongoCollection<T>> _mongoCollections = new ConcurrentDictionary<RuntimeTypeHandle, IMongoCollection<T>>();
public MongoRepository(IOptions<MongoOptions> optionsAccessor)
{
if (optionsAccessor == null)
{
throw new ArgumentNullException(nameof(optionsAccessor));
}
_options = optionsAccessor.Value;
if (_mongoClient == null)
{
lock (_obj)
{
if (_mongoClient == null)
{
_mongoClient = new MongoClient(_options.ConnectionString);
_mongoDatabase = _mongoClient.GetDatabase(_options.DataBaseName);
}
}
}
}
public void Insert(T document)
{
this.GetCollection(document).InsertOne(document);
}
private IMongoCollection<T> GetCollection(T document)
{
if (_mongoCollections.TryGetValue(document.GetType().TypeHandle, out IMongoCollection<T> collection))
{
return collection;
}
collection = _mongoDatabase.GetCollection<T>(typeof(T).Name);
_mongoCollections.TryAdd(document.GetType().TypeHandle, collection);
return collection;
}
}
public class MongoOptions
{
public string ConnectionString { get; set; }
public string DataBaseName { get; set; }
}
public static class MongoServiceCollectionExtensions
{
public static IServiceCollection AddMongo(this IServiceCollection services, Action<MongoOptions> setupAction)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (setupAction == null)
{
throw new ArgumentNullException(nameof(setupAction));
}
services.AddOptions();
services.Configure(setupAction);
services.AddScoped(typeof(MongoRepository<>));
return services;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddMongo(options =>
{
options.ConnectionString = "mongodb://localhost:27017";
options.DataBaseName = "oneaspnet";
});
}