配置 class 的依赖注入到静态文档数据库存储库(VS2015 DNX 项目)

Dependency Injection of configuration class into static Document DB repository (VS2015 DNX project)

我在解决方案的基础结构层中有一个基本文档数据库存储库。我将此存储库基于 this GitHub project,这是一个静态 class,我的其他域模型存储库使用它。

在我的 API 图层中,我有 config.json 特定于环境的文件。我想使用依赖注入来使用我的配置 class,它读取在更深的基础设施层的 API 层中定义的 DocumentDB 设置。 This Whosebug answer 详细介绍了如何将 DI 与 API 控制器一起使用,但是我不知道在这种情况下如何使用 DI,作为静态 class,我没有构造函数.是否可以将 DI 与我的静态存储库一起使用?如果没有,我应该如何将配置设置读入基础设施层?

我的配置选项class(在基础设施层):

public class ConfigurationOptions
{
    public string EndpointUri { get; set; }
}

My DocumentDbRepository class(在基础设施层):

public static class DocumentDbRepository<T>
{
    // I want to read these strings from my config.json files
    private static string EndpointUri { get; } = ConfigurationOptions.EndpointUri;

    //...


    private static Document GetDocument(string id)
    {
        return Client.CreateDocumentQuery(Collection.DocumentsLink)
            .Where(d => d.Id == id)
            .AsEnumerable()
            .FirstOrDefault();
    }
}

我的 Startup 的一部分 class(在我的 API 层)

public class Startup
{
    public IConfiguration Configuration { get; set; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<ConfigurationOptions>(options =>
            options.EndpointUri = Configuration.Get("EndpointUri"));

    // ...

    }

// ...

}

我相信你快到了。

你要迈出的第一步就快完成了。

在你的 startup.cs 中,你有

services.Configure<ConfigurationOptions>(options =>
        options.EndpointUri = Configuration.Get("EndpointUri"));

你可以打电话

services.Configure<ConfigurationOptions>(Configuration);

服务将映射您的 class 的 EndpointUri 属性。到这里第一步就完成了。

现在,按照您链接的 post,您可以将配置选项发送到控制器,例如:

    public class SomeController
{
    private string _endpointUrl;
    public SomeController(IOptions<ConfigurationOptions> options)
    {
        _endpointUrl = options.Options.EndpointUri;
    }
}

但是,根据我的假设,您希望在 DocumentDbRepository 中拥有 EndpointUri。您可以通过两种方式做到这一点:

1 ---------------------------------- --------------

您可以在 DocumentDbRepository 中创建一个构造函数来接收 EndpointUri 并在您的控制器中调用它,如下所示:

    public class SomeController
{
    private DocumentDbRepository _documentDbRepositoy
    public SomeController(IOptions<ConfigurationOptions> options)
    {
        _documentDbRepositoy = new DocumentDbRepository (options.Options.EndpointUri);
    }
}

2 ---------------------------------- ------------------

您可以将 DocumentDbRepository 注入所有控制器。为此,我建议您创建一个接口 IDocumentDbRepository,然后在启动时对其进行配置,使其成为单例或作用域或 trasiend(有关更多信息,请参见 link

为此,让我们从您的 DocumentDbRepository 开始

public static class DocumentDbRepository<T> : IDocumentDbRepository<T>
{
    private string EndpointUri { get; private set;}

    public DocumentDbRepository(IOptions<ConfigurationOptions> options){
        EndpointUri = options.Options.EndpointUri;
    }

    //...


}

然后,在 startup.cs 处将其设置为单例(在此示例中)

public void ConfigureServices(IServiceCollection services){
    services.Configure<ConfigurationOptions(Configuration);
    services.AddSingleton<IDocumentDbRepository, DocumentDbRepository>();
    // ...

}

通过这样做,如果您的控制器依赖于 IDocumentDbRepository,将提供单例:

    public class SomeController
{
    private DocumentDbRepository _documentDbRepositoy
    public SomeController(IDocumentDbRepository documentDbRepository)
    {
        _documentDbRepositoy = documentDbRepository
    }
}