快速使用Monimal API 快速集成Orleans 微软官网地址如下:
https://learn.microsoft.com/zh-cn/dotnet/orleans/quickstarts/build-your-first-orleans-app?source=recommendations&tabs=visual-studio
当然它的存储grain存储采用的是内存级别存储,我缓存了mssql 存储。如果是内存存储使用如下代码就Ok
siloBuilder.AddMemoryGrainStorage("urls");
我采用的是数据库存储:
siloBuilder.AddAdoNetGrainStorage("OrleansStorage", options =>
{
options.Invariant = "System.Data.SqlClient";
options.ConnectionString = "Server=.;Database=OrleansStorage;Persist Security Info=True;User ID=sa;password=Sasa123;";
});
当然这过程中需要引入的库如下:
Microsoft.Orleans.Persistence.AdoNet: ado.net存储
Microsoft.Orleans.Server :orleans 开启服务
System.Data.SqlClient :ado 操作数据库驱动程序,ado.net 开发使用库
Program.cs 完整代码如下:
using Microsoft.AspNetCore.Http.Extensions;
using Orleans.Runtime;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseOrleans(siloBuilder =>
{
siloBuilder.UseLocalhostClustering();
//siloBuilder.AddMemoryGrainStorage("urls");
siloBuilder.AddAdoNetGrainStorage("OrleansStorage", options =>
{
options.Invariant = "System.Data.SqlClient";
options.ConnectionString = "Server=.;Database=OrleansStorage;Persist Security Info=True;User ID=sa;password=Sasa123;";
});
});
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.MapGet("/", () => "Hello World!");
app.MapGet("/shorten/{*path}",
async (IGrainFactory grains, HttpRequest request, string path) =>
{
// Create a unique, short ID
var shortenedRouteSegment = Guid.NewGuid().GetHashCode().ToString("X");
// Create and persist a grain with the shortened ID and full URL
var shortenerGrain = grains.GetGrain<IUrlShortenerGrain>(shortenedRouteSegment);
await shortenerGrain.SetUrl(path);
// Return the shortened URL for later use
var resultBuilder = new UriBuilder(request.GetEncodedUrl())
{
Path = $"/go/{shortenedRouteSegment}"
};
return Results.Ok(resultBuilder.Uri);
});
app.MapGet("/go/{shortenedRouteSegment}",
async (IGrainFactory grains, string shortenedRouteSegment) =>
{
// Retrieve the grain using the shortened ID and redirect to the original URL
var shortenerGrain = grains.GetGrain<IUrlShortenerGrain>(shortenedRouteSegment);
var url = await shortenerGrain.GetUrl();
return Results.Redirect(url);
});
app.Run();
#region grain 粒度
/// <summary>
/// grain 接口 粒度
/// </summary>
public interface IUrlShortenerGrain : IGrainWithStringKey
{
Task SetUrl(string fullUrl);
Task<string> GetUrl();
}
public class UrlShortenerGrain : Grain, IUrlShortenerGrain
{
private readonly IPersistentState<UrlDetails> _state;
public UrlShortenerGrain(
[PersistentState(stateName: "url",storageName: "urls")]
IPersistentState<UrlDetails> state)
{
_state = state;
}
public async Task SetUrl(string fullUrl)
{
_state.State = new UrlDetails()
{
ShortenedRouteSegment = this.GetPrimaryKeyString(),
FullUrl = fullUrl
};
await _state.WriteStateAsync();
}
public Task<string> GetUrl()
{
return Task.FromResult(_state.State.FullUrl);
}
}
[GenerateSerializer]
public record UrlDetails
{
public string FullUrl { get; set; }
public string ShortenedRouteSegment { get; set; }
}
#endregion
特别注意如果是需要数据库存储:除了加入上面包外,还需要执行相应脚本,脚本到微软官网地址找:
https://learn.microsoft.com/zh-cn/dotnet/orleans/host/configuration-guide/adonet-configuration 当然需要自己按数据库配置链接建立一个空库,然后执行对应SQL脚本。否则会运行报错
然后对应执行相应需要存储脚本:也就是官网对应的持久化,提醒、集群脚本。