繁体   English   中英

无法访问方法(带有ASP.NET Core的Azure表)

[英]Can't access method (Azure Tables with ASP.NET Core)

我试图从另一个类(我的视图的控制器)访问一个方法,在该类中我与Azure表建立连接并更新实体。

我的“控制器”拨打电话如下:

// this requires an object reference
HttpResponseMessage httpResponseMessage = AzureTableConn.UpdateTenantSettings(post);

这是我的类,其中包含我与Azure Tables的连接,其中我从Azure Key Vault中提取了连接字符串:

public class AzureTableConn
{
    public AzureTableConn(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    private IConfiguration Configuration { get; set; }

    private CloudTable TableConnection(string tableName)
    {
        var connectionString = Configuration["AzureTableStorageConnectionString"];
        var cloudStorageAccount = CloudStorageAccount.Parse(connectionString);
        CloudTableClient tableClient = cloudStorageAccount.CreateCloudTableClient();
        CloudTable cloudTable = tableClient.GetTableReference(tableName);
        return cloudTable;            
    }

    public HttpResponseMessage UpdateTenantSettings(TenantSettingsModel tenantSettingsModel)
    {
        CloudTable cloudTable = TableConnection("TenantSettings");
        Task<TableResult> mergeEntity = cloudTable.ExecuteAsync(TableOperation.Merge(tenantSettingsModel));
        return new HttpResponseMessage();
    }
}

我希望能够从控制器类中调用UpdateTenantSettings方法,但它说我需要一个实例。 这很有意义,但是如果不向默认构造函数提供IConfiguration对象,就无法创建实例。 我感觉好像被困在了22号鱼钩中,并且不了解如何解决它。

我的目的是在我的应用程序中使用AzureTableConn类,而不是每次我想读/写到Azure表时都为其创建新实例。 我尝试将AzureTableConn类设置为静态,并且这可以解决对象引用错误,但我对IConfiguration引用却遇到问题。 我还尝试将构造函数设置为静态,但这又将其中断,并告诉我“静态构造函数必须无参数”。

我还尝试将以下内容添加到我的Startup.cs文件中:

services.Configure<AzureTableConnectionString>(Configuration);

其中AzureTableConnectionString定义为:

public class AzureTableConnectionString
{
    public string ConnectionString { get; set; }
}

但是,我不知道这是否正确或如何实现。

因此,我如何才能将我的Azure Key Vault配置设置提取到一个类中,然后使用同一类中的方法来重新使用与Azure表的连接,并从需要提供参数(例如实体,数据)来创建/更新/删除/等?

您可以通过向DI容器注册AzureTableConn来让ASP.NET Core为您处理此问题,如下所示(在ConfigureServices ):

services.AddSingleton<AzureTableConn>();

为了在您的控制器中使用它,只需将其作为参数添加到控制器的构造函数中,并存储以供以后使用,如下所示:

public class SomeController : Controller
{
    private readonly AzureTableConn _azureTableConn;

    public SomeController(AzureTableConn azureTableConn)
    {
        _azureTableConn = azureTableConn;
    }

    public IActionResult SomeAction()
    {
        ...
        var httpResponseMessage = _azureTableConn.UpdateTenantSettings(post);
        ...
    }
}

在此示例中,您可以在控制器的任何操作中使用_azureTableConn 因为我们使用过AddSingleton ,所以每个控制器都将获得相同的实例,该实例仅创建一次。

文档很好地解释了这一点: ASP.NET Core中的依赖注入

考虑创建一个抽象。

public interface IAzureTableConnection {
    Task<HttpResponseMessage> UpdateTenantSettings(TenantSettingsModel tenantSettingsModel);
}

通常建议避免耦合到IConfiguration 相反,在合成根目录中获得所需的内容,并将其传递给依赖类。

Startup

private IConfiguration Configuration { get; set; }

public void ConfigureServices(IServiceCollection services) {

    //...

    var connectionString = Configuration["AzureTableStorageConnectionString"];
    var cloudStorageAccount = CloudStorageAccount.Parse(connectionString);
    CloudTableClient tableClient = cloudStorageAccount.CreateCloudTableClient();

    services.AddScoped<IAzureTableConnection>(_ => new AzureTableConnection(tableClient));

    //...
}

然后,依赖类仅需要依赖已配置的CloudTableClient

public class AzureTableConnection: IAzureTableConnection {
    private readonly CloudTableClient tableClient;

    public AzureTableConnection(CloudTableClient tableClient) {
        this.tableClient = tableClient;
    }

    private CloudTable TableConnection(string tableName) {
        CloudTable cloudTable = tableClient.GetTableReference(tableName);
        return cloudTable;            
    }

    public async Task<HttpResponseMessage> UpdateTenantSettings(TenantSettingsModel tenantSettingsModel) {
        CloudTable cloudTable = TableConnection("TenantSettings");
        var mergeEntity = await cloudTable.ExecuteAsync(TableOperation.Merge(tenantSettingsModel));

        //...do something with the result

        return new HttpResponseMessage();
    }
}

您的控制器将通过构造函数注入显式依赖IAzureTableConnection抽象,并在需要时可以访问注入的实例

public class MyController : Controller {
    private readonly IAzureTableConnection tableConnection;

    public MyController(IAzureTableConnection tableConnection) {
        this.tableConnection = tableConnection;
    }

    public async Task<IActionResult> MyAction() {


        //...

        HttpResponseMessage httpResponseMessage = await tableConnection.UpdateTenantSettings(post);

        //...
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM