![](/img/trans.png)
[英]CS0311 C# The type cannot be used as type parameter 'TContext' in the generic type or method. EntityFrameworkCore
[英]C# Azure Function app - Moq Tests - Adding dependency injection fails with CS0311
我有以下 function:
public class WidgetRequest {
[FunctionName("CreateWidget")]
public static async Task<IActionResult> CreateWidget(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "/widget")] HttpRequest req,
[Queue("widgets"), StorageAccount("StorageForWidgets")] ICollector<string> messageQueue,
ILogger log)
{
ProvisionedWidgetsRepository storage = new ProvisionedWidgetsRepository();
WidgetResponse response = new WidgetResponse ();
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var widgetRequest = JsonConvert.DeserializeObject<Widget>(content);
if (widgetRequest .name != null){
//add the request to queue for processing
messageQueue.Add(JsonConvert.SerializeObject(widgetRequest));
//also add to provisioned storage table
response = await storage.ProvisioningRequest(widgetRequest , req.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString(), "enqueued");
}
else {
response.status = "Error: Invalid Request";
response.requestId=null;
}
return new OkObjectResult(JsonConvert.SerializeObject(response));
}
我有以下測試:
[Fact]
public async void widget_creation_requests_should_be_stored_in_queue(){
var messageQueue = TestFactory.CreateAzureStorageQueue();
var storageTable = TestFactory.CreateAzureStorageTable();
var request = TestFactory.CreateWidgetRequest();
var response = (OkObjectResult)await WidgetRequest.CreateWidget(request, messageQueue, logger);
Assert.NotNull(response);
Assert.True(((AzureStorageQueueTestClient<string>)messageQueue).Messages.Count > 0);
}
測試失敗是因為我不知道如何傳入我在測試中旋轉的模擬存儲表(“var storageTable”)。 在實際的function中可以看到,我手動實例化了一個新的存儲object這樣:
ProvisionedWidgetsRepository storage = new ProvisionedWidgetsRepository();
我不傳遞它。任何提示將不勝感激。
謝謝
編輯 1
所以我重構了將存儲邏輯移出到一個單獨的 class 中,並帶有一個支持依賴注入的接口。 具有主要邏輯的代碼現在有一個構造函數,並使用新接口。 它看起來像這樣:
public class WidgetRequest {
//Using Interface for storage so we can dependency inject for testing.
private IWidgetRepositoryController storage;
public WidgetRequest(IWidgetRepositoryController storage)
{
this.storage = storage;
}
[FunctionName("CreateWidget")]
public static async Task<IActionResult> CreateWidget(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "/widget")] HttpRequest req,
[Queue("widgets"), StorageAccount("StorageForWidgets")] ICollector<string> messageQueue,
ILogger log)
{
//ProvisionedWidgetsRepository storage = new ProvisionedWidgetsRepository();
WidgetResponse response = new WidgetResponse ();
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var widgetRequest = JsonConvert.DeserializeObject<Widget>(content);
if (widgetRequest .name != null){
//add the request to queue for processing
messageQueue.Add(JsonConvert.SerializeObject(widgetRequest));
//also add to provisioned storage table
response = await storage.AddToTable(widgetRequest , req.HttpContext.Items["MS_AzureFunctionsRequestID"].ToString(), "enqueued");
}
else {
response.status = "Error: Invalid Request";
response.requestId=null;
}
return new OkObjectResult(JsonConvert.SerializeObject(response));
}
這是新存儲 Controller class 的樣子,以及界面:
public interface IWidgetRepositoryController
{
Task<WidgetResponse> AddToTable(Widget widgetRequest, string requestID, string partitionName);
}
public class WidgetRepositoryController
{
public async Task<WidgetResponse> AddToTable(Widget widgetRequest, string requestID, string partitionName)
{
ProvisionedWidgetRepository storage = new ProvisionedWidgetRepository ();
WidgetResponse response = await storage.ProvisioningRequest(widgetRequest, requestID, partitionName);
return response;
}
}
到目前為止,上面的所有邏輯似乎都沒有問題——沒有錯誤。 但我現在正在嘗試創建 Startup.cs 文件。 我收到錯誤 CS0311。
這是代碼:
[assembly: FunctionsStartup(typeof(Az.Fn.Widgets.Startup))]
namespace Az.Fn.Widget
{
public class Startup: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IWidgetRepositoryController, WidgetRepositoryController>();
}
}
完整錯誤:
類型“Az.Fn.Widgets.WidgetRepositoryController”不能用作泛型類型或方法“ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)”中的類型參數“TImplementation”。 沒有從“Az.Fn.Widgets.WidgetRepositoryController”到“Az.Fn.Widgets.IWidgetRepositoryController”的隱式引用轉換。
根據 ThrowingSpoon 的評論,我不得不重構以支持 DI,然后我遇到了一個錯誤。 我不得不從這個改變 WidgetRespositoryController class :
public class WorkspaceRepositoryController
對此:
public class WorkspaceRepositoryController : IWorkspaceRepositoryController
而且好像很開心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.