ASP.NET 核心中的 DI 异常:无法创建类型 'MyProject.Data.ITableRepositories' 的实例

DI Exception in ASP.NET Core: Could not create an instance of type 'MyProject.Data.ITableRepositories'

我尝试按照 ASP.NET 核心 1.1 下的文章 Access Azure Storage in an ASP.NET Core application using Connected Services 将我的 Web 应用程序连接到 Azure 表。

但问题是,在 ASP.NET Core 和 Microsoft.WindowsAzure.Storage nuget 下,我无法访问 Syncronous 方法。

我是异步编程的初学者,所以下面的代码可能有点疯狂,但这是我的 "Async Azure Connector" 版本:

// Model
public class Record : TableEntity {
    public Record() { }
    public Record(string id, string name, string partition = "record") {
        this.RowKey = id;
        this.PartitionKey = partition;
        this.Name = name;
    }
    [...]
}    

// Data Interface
public interface ITableRepositories {
    Task<bool> CreateRecordAsync(Record record);
    Task<List<Record>> GetRecordsAsync();
    Task<Record> GetRecordAsync(string key, string partitionKey = "record");
}

// Data Class
public class TableClientOperationsService : ITableRepositories {
    private string connectionString;
    private CloudTable recordTable;

    public TableClientOperationsService() { }
    public TableClientOperationsService(IOptions<AppSecrets> optionsAccessor) {
        connectionString = optionsAccessor.Value.MyProjectTablesConnectionString;
    }

    public CloudTable RecordTable {
        get {
            if (recordTable == null) {
                recordTable = GetTable("Record");
            }
            return recordTable;
        }
    }

    private CloudTable GetTable(string tableName) {
        [.connectionString.]
        table.CreateIfNotExistsAsync().Wait();
        return table;
    }

    public async Task<T> Get<T>(string partitionKey, string rowKey, string tableName) where T : ITableEntity, new()
    {            [...]        }

    public async Task<bool> CreateRecordAsync(Record record) {
        TableOperation insertOperation = TableOperation.Insert(record);
        await this.RecordTable.ExecuteAsync(insertOperation);
        return true;
    }

    public async Task<Record> GetRecordAsync(string key, string partitionKey = "record") {
        const string TableName = "Record";
        Record myRecord = await Get<Record>(partitionKey, key, TableName);
        return myRecord;
    }

    public async Task<List<Record>> GetRecordsAsync() {
        TableQuery<Record> recordsQuery = new TableQuery<Record>().Where(
            TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "record"));
        EntityResolver<Record> recordResolver = null;
        List<Record> myList = new List<Record>();
        TableQuerySegment<Record> currentSegment = null;
        while (currentSegment == null || currentSegment.ContinuationToken != null) {
            currentSegment = await recordTable.ExecuteQuerySegmentedAsync(
                recordsQuery,
                recordResolver,
                currentSegment != null ? currentSegment.ContinuationToken : null);

            myList.AddRange(currentSegment.Results);
        }
        return myList;
    }
}

// Setup.cs configuration
public void ConfigureServices(IServiceCollection services)
{
    services.AddOptions();
    services.Configure<AppSecrets>(Configuration);

    // association of ITableRepositories with TableClientOperationsService
    services.AddSingleton(typeof(ITableRepositories), typeof(TableClientOperationsService));

    services.AddMvc();        
}


// Usage in the Controller
public class HelloWorldController : Controller {
    public async Task<string> ReadTables1(ITableRepositories repository) {
        StringBuilder response = new StringBuilder();
        response.AppendLine("Here is your Record Table:");
        var items = await repository.GetRecordsAsync();
        foreach (Record item in items) {
            response.AppendLine($"RowKey: {item.RowKey}; Name: {item.Name}");
        }
        return response.ToString();
    }    

但是,当我尝试通过 /HelloWorld/ReadTables1 访问控制器操作时 它给我以下内容:

InvalidOperationException: Could not create an instance of type 'MyProject.Data.ITableRepositories'. Model bound complex types must not be abstract or value types and must have a parameterless constructor.

可能是我在服务中注册不正确,因为我的 TableClientOperationsService class 不是抽象的并且有一个无参数的构造函数?如何解决?

您应该在控制器的构造函数中获取 ITableRepositories 参数,而不是在从 DI 获取它的方法中。

public class HelloWorldController : Controller
{
    private readonly ITableRepositories _tableRepository;
    public HelloWorldController(ITableRepositories tableRepository)
    {
         _tableRepository = tableRepository;
    }
}