[英]Orleans 7.0 GrainService registration
我應該如何在 Orleans 7.0 中注冊 GrainService?
我有谷物服務:
public interface IAlfaGrainService : IGrainService
{
Task<IReadOnlyList<AlfaData>> TestMethod();
}
[Reentrant]
public class AlfaGrainService : GrainService, IAlfaGrainService
{
readonly IGrainFactory _grainFactory;
private readonly ILogger<AlfaGrainService> logger;
public AlfaGrainService(
IServiceProvider services,
Silo silo,
ILoggerFactory loggerFactory,
IGrainFactory grainFactory,
ILogger<AlfaGrainService> logger)
: base(GrainId.Create(nameof(AlfaGrainService), Guid.Empty.ToString()), silo, loggerFactory)
{
_grainFactory = grainFactory;
this.logger = logger;
}
public async Task<IReadOnlyList<AlfaData>> TestMethod()
{
logger.LogInformation("TestMethod() hit");
// TODO: custom logic here.
var data = new List<AlfaData> {
new AlfaData
{
Id = 1,
Name = "Test 1"
},
new AlfaData
{
Id = 2,
Name = "Test 2"
}
};
return await Task.FromResult(data);
}
}
GrainServiceClient(因為我想從 Grain 調用 GrainService):
public interface IAlfaGrainServiceClient : IGrainServiceClient<IAlfaGrainService>, IAlfaGrainService
{
}
public class AlfaGrainServiceClient : GrainServiceClient<IAlfaGrainService>, IAlfaGrainServiceClient
{
public AlfaGrainServiceClient(
IServiceProvider serviceProvider)
: base(serviceProvider)
{ }
public Task<IReadOnlyList<AlfaData>> TestMethod()
{
// Not sure how to get grainService reference:
var grainId = GrainId.Create(nameof(AlfaGrainService), Guid.Empty.ToString());
var service = GetGrainService(grainId);
// -------------------------------------
return service.TestMethod();
}
}
我想從中調用 GrainService 的 Grain(通過代理 GrainServiceClient):
public interface IAlfaGrain: IGrainWithStringKey
{
Task<IReadOnlyList<AlfaData>> LoadData();
}
public class AlfaGrain: Grain, IAlfaGrain
{
private readonly IAlfaGrainServiceClient alfaGrainServiceClient;
public AlfaGrain(
IAlfaGrainServiceClient alfaGrainServiceClient)
{
this.alfaGrainServiceClient = alfaGrainServiceClient;
}
public async Task<IReadOnlyList<AlfaData>> LoadData()
{
return await alfaGrainServiceClient.TestMethod();
}
}
但是如果我像這樣注冊 GrainService:
siloBuilder
.AddGrainService<AlfaGrainService>() // Register grainService like this ??
.ConfigureServices(services =>
{
services.AddSingleton<IAlfaGrainServiceClient, AlfaGrainServiceClient>();
});
我在啟動應用程序時出錯:
A suitable constructor for type 'GrainServiceApp.GrainServices.AlfaGrainService' could not be located. Ensure the type is concrete and all parameters of a public constructor are either registered as services or passed as arguments. Also ensure no extraneous arguments are provided.
可能是因為 GrainServiceFactory() (Orleans.Hosting.GrainServicesSiloBuilderExtensions) 沒有使用所有 ctor 參數創建實例。
Microsoft 文檔僅與 Orleans 的先前版本有關,因此不適用於我的情況。
有人知道如何在 Orleans 7.0 中注冊 GrainService 嗎?
所有代碼都在github
我已經找到了解決方案,而且非常簡單。
我需要將GrainId注入 GrainService 並將其傳遞到 base class:
public AlfaGrainService( GrainId grainId, Silo silo, IServiceProvider services, ILoggerFactory loggerFactory, ILogger<AlfaGrainService> logger): base(grainId, silo, loggerFactory) { this.logger = logger; }
然后在 GrainServiceClient 中,我通過 CurrentGrainReference.GrainId 獲得了GrainService實例,如下所示:
public Task<IReadOnlyList<AlfaData>> TestMethod() { var service = GetGrainService(CurrentGrainReference.GrainId); return service.TestMethod(); }
我已經更新了GitHub上的示例
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.