我认为,Retic 的做法还不错。
让我们继续他的回答并将数据库配置提取到单独的方法 ConfigureMongoDb 中:
public void ConfigureServices(IServiceCollection services)
{
ConfigureMongoDb(services);
services.AddControllers()
.AddNewtonsoftJson(options => options.UseMemberCasing());
}
private void ConfigureMongoDb(IServiceCollection services)
{
var settings = GetMongoDbSettings();
var db = CreateMongoDatabase(settings);
var collectionA = db.GetCollection<Author>(settings.AuthorsCollectionName);
services.AddSingleton(collectionA);
services.AddSingleton<AuthorService>();
var collectionB = db.GetCollection<Book>(settings.BooksCollectionName);
services.AddSingleton(collectionB);
services.AddSingleton<BookService>();
}
private BookstoreDatabaseSettings GetMongoDbSettings() =>
Configuration.GetSection(nameof(BookstoreDatabaseSettings)).Get<BookstoreDatabaseSettings>();
private IMongoDatabase CreateMongoDatabase(BookstoreDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
return client.GetDatabase(settings.DatabaseName);
}
或更紧凑的形式:
private void ConfigureMongoDb(IServiceCollection services)
{
var settings = GetMongoDbSettings();
var db = CreateMongoDatabase(settings);
AddMongoDbService<AuthorService, Author>(settings.AuthorsCollectionName);
AddMongoDbService<BookService, Book>(settings.BooksCollectionName);
void AddMongoDbService<TService, TModel>(string collectionName)
{
services.AddSingleton(db.GetCollection<TModel>(collectionName));
services.AddSingleton(typeof(TService));
}
}
这种方法的缺点是,所有与 mongodb 相关的实例(服务除外)都是在启动时创建的。
这并不总是很糟糕,因为在设置错误或其他错误的情况下,您会在启动时立即得到响应。
如果您想对此实例进行延迟初始化,可以使用工厂方法注册数据库创建和集合检索:
public void ConfigureMongoDb(IServiceCollection services)
{
var settings = GetMongoDbSettings();
services.AddSingleton(_ => CreateMongoDatabase(settings));
AddMongoDbService<AuthorService, Author>(settings.AuthorsCollectionName);
AddMongoDbService<BookService, Book>(settings.BooksCollectionName);
void AddMongoDbService<TService, TModel>(string collectionName)
{
services.AddSingleton(sp => sp.GetRequiredService<IMongoDatabase>().GetCollection<TModel>(collectionName));
services.AddSingleton(typeof(TService));
}
}
在服务中,您只需注入已注册的集合。
public class BookService
{
private readonly IMongoCollection<Book> _books;
public BookService(IMongoCollection<Book> books)
{
_books = books;
}
}
public class AuthorService
{
private readonly IMongoCollection<Author> _authors;
public AuthorService(IMongoCollection<Author> authors)
{
_authors = authors;
}
}