理论:因此,在我试图不断改进的过程中,我遇到了这个难题。下面的代码是现有代码。我的理解是,该应用程序实际上将为以下每个单例建立单独的连接。因为所有这些都指向同一实例,所以我可以肯定的是,如果您命中具有两个此类的索引,那么您对cosmos DB的使用将更大。
问题:是否可以减少以下单例声明以使用T的通用对象,以便可以相对于N + 1使用一个单例?
services.AddSingleton<IDocumentDBRepository<Car>>(new DocumentDBRepository<Car>("Database"));
services.AddSingleton<IDocumentDBRepository<House>>(new DocumentDBRepository<House>("Database"));
services.AddSingleton<IDocumentDBRepository<Employer>>(new DocumentDBRepository<Employer>("Database"));
services.AddSingleton<IDocumentDBRepository<Photo>>(new DocumentDBRepository<Photo>("Database"));
此外,如果您对我有其他建议,甚至需要其他建议,请提出建议,以便我也可以进行研究!
您可以将DocumentDBRepository
类更改为直接接受DocumentClient
。这样,它将不会创建新客户端,而是使用指定的客户端。
但是,我认为您不应该这样做。因为,CosmosDB使用情况计数基于RU非连接。 CosmosDB pricing的链接
Azure Cosmos DB帐单用于配置吞吐量和消耗的存储按小时。
提供的吞吐量以每秒请求单位表示(RU / s),可用于各种数据库操作(例如,插入,读取,替换,更新,删除,查询等)。对于例如,1 RU / s足以处理一个最终的一致性每秒读取1K项,并且5 RU / s足以处理每秒写入1K项。
存储空间是针对用于SSD支持的数据和索引的每GB计费的。
您似乎有几个问题:
A]您的Cosmos用法仅取决于您对数据库的调用,而不取决于您创建的访问数据库的服务数量。
B)通过查看您的代码,看来您正在使用Microsoft.Extensions.DependencyInjection
。该框架支持开放式泛型,从理论上讲,它可以将您的四个单例注册减少为使用开放式泛型类型的单个注册。类似于:
.AddSingleton(typeof(IDocumentDBRepository<>), typeof(DocumentDBRepository<>)
这里打开的通用服务类型为IDocumentDBRepository<>
,实现类型为DocumentDBRepository<>
。当依赖项注入框架必须创建IDocumentDBRepository<Car>
服务时,它将创建DocumentDBRepository<Car>
实例。
不幸的是,在您的情况下这是不可能的,因为您正在使用需要为四个服务中的每一个提供参数的构造函数。但是,您也许可以重构服务来解决此问题。一种(通用)解决方案是引入工厂:
public interface IDocumentDBRepositoryFactory<T>
{
IDocumentDBRepository<T> Create(string databaseName);
}
和实现:
internal class DocumentDBRepositoryFactory<T>
{
public IDocumentDBRepository<T> Create(string databaseName)
=> return new DocumentDBRepository(databaseName);
}
然后您注册该工厂(使用开放的通用名称):
.AddSingleton(typeof(IDocumentDBRepositoryFactory<>), typeof(DocumentDBRepositoryFactory<>)
现在,存储库的使用者将必须使用IDocumentDBRepositoryFactory<T>
实例并调用Create
方法并提供数据库名称以获取实际的IDocumentDBRepository<T>
实例。另一种选择是摆脱factory方法的databaseName
参数,而是配置factory实例来提供该参数(大概是通过配置)。
引入工厂使您可以推迟从配置系统到系统执行的决定。在这种情况下,决定要连接到哪个数据库。