[英]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.