无法访问方法(具有 ASP.NET 核心的 Azure 表)
Can't access method (Azure Tables with ASP.NET Core)
我正在尝试从另一个 class(我的视图控制器)访问一个方法,我在其中连接到 Azure 表并更新实体。
我的'controller'调用如下:
// this requires an object reference
HttpResponseMessage httpResponseMessage = AzureTableConn.UpdateTenantSettings(post);
这是我的 class,其中包含我与 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();
}
}
我希望能够从我的控制器 class 调用 UpdateTenantSettings
方法,但它说我需要一个实例。这是有道理的,但是我不能在不向默认构造函数提供 IConfiguration
对象的情况下创建实例。我觉得自己陷入了陷阱 22 并且不知道如何绕过它。
我的意图是在我的应用程序中使用我的 AzureTableConn
class,而不是每次我想 read/write 到 Azure 表时都创建它的新实例。我已经尝试将我的 AzureTableConn
class 设置为静态,虽然这可以解决对象引用错误,但我在引用 IConfiguration
时遇到问题。我也试过将我的构造函数设置为 static 但这又打破了它并告诉我 "a static constructor must be parameterless".
我还尝试将以下内容添加到我的 Startup.cs
文件中:
services.Configure<AzureTableConnectionString>(Configuration);
其中 AzureTableConnectionString
定义为:
public class AzureTableConnectionString
{
public string ConnectionString { get; set; }
}
但是,我不知道这是否正确或如何实现。
那么我如何才能将我的 Azure Key Vault 配置设置拉到 class 中,然后使用同一 class 中的方法重新使用与 Azure 表的连接,并从中访问这些方法另一个 class 我需要向 create/update/delete/etc.?
提供实体(数据)等参数
您可以让 ASP.NET 核心通过向 DI 容器注册 AzureTableConn
来为您处理这个问题,就像这样(在 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
,所以每个控制器都会得到相同的实例,它只会被创建一次。
文档很好地解释了这一点:Dependency injection in ASP.NET Core。
考虑创建抽象。
public interface IAzureTableConnection {
Task<HttpResponseMessage> UpdateTenantSettings(TenantSettingsModel tenantSettingsModel);
}
通常建议避免耦合到 IConfiguration
。相反,在组合根中获取您需要的内容并将其传递给从属 class.
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));
//...
}
依赖的 class 将只需要依赖配置的 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);
//...
}
}
我正在尝试从另一个 class(我的视图控制器)访问一个方法,我在其中连接到 Azure 表并更新实体。
我的'controller'调用如下:
// this requires an object reference
HttpResponseMessage httpResponseMessage = AzureTableConn.UpdateTenantSettings(post);
这是我的 class,其中包含我与 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();
}
}
我希望能够从我的控制器 class 调用 UpdateTenantSettings
方法,但它说我需要一个实例。这是有道理的,但是我不能在不向默认构造函数提供 IConfiguration
对象的情况下创建实例。我觉得自己陷入了陷阱 22 并且不知道如何绕过它。
我的意图是在我的应用程序中使用我的 AzureTableConn
class,而不是每次我想 read/write 到 Azure 表时都创建它的新实例。我已经尝试将我的 AzureTableConn
class 设置为静态,虽然这可以解决对象引用错误,但我在引用 IConfiguration
时遇到问题。我也试过将我的构造函数设置为 static 但这又打破了它并告诉我 "a static constructor must be parameterless".
我还尝试将以下内容添加到我的 Startup.cs
文件中:
services.Configure<AzureTableConnectionString>(Configuration);
其中 AzureTableConnectionString
定义为:
public class AzureTableConnectionString
{
public string ConnectionString { get; set; }
}
但是,我不知道这是否正确或如何实现。
那么我如何才能将我的 Azure Key Vault 配置设置拉到 class 中,然后使用同一 class 中的方法重新使用与 Azure 表的连接,并从中访问这些方法另一个 class 我需要向 create/update/delete/etc.?
提供实体(数据)等参数您可以让 ASP.NET 核心通过向 DI 容器注册 AzureTableConn
来为您处理这个问题,就像这样(在 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
,所以每个控制器都会得到相同的实例,它只会被创建一次。
文档很好地解释了这一点:Dependency injection in ASP.NET Core。
考虑创建抽象。
public interface IAzureTableConnection {
Task<HttpResponseMessage> UpdateTenantSettings(TenantSettingsModel tenantSettingsModel);
}
通常建议避免耦合到 IConfiguration
。相反,在组合根中获取您需要的内容并将其传递给从属 class.
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));
//...
}
依赖的 class 将只需要依赖配置的 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);
//...
}
}