持久化
Grain可以具有多个与之关联的已命名的持久数据对象(named persistent data objects)。在激活Grain时,状态会从存储中加载,便于在请求时使用。Grain的持久化使用可扩展插件模型,可以使用任何数据库的存储提供器(storage provider)。该持久化模型设计简明,无意涵盖所有数据访问模式。Grain也可以直接访问数据库,无需使用Grain持久化模型。
如上图所示,UserGrain实体有两个状态:Profile和Cart。这两种状态分别存在不同的存储系统中。
目标
- 一个Grain可以具有多个已命名的持久化数据对象;
- 可以有多个存储提供器,每个存储提供器配置可以不同,也可以由不同的存储系统支持;
- 社区可以开发和发布存储提供器;
- 存储提供器对它们如何在持久化后台存储中保存Grain状态,具有完全的控制权。
结论:Orleans没有提供全面的ORM存储解决方案,但允许通过定制存储提供器来支持具体的ORM需求。
包
Orleans的Grain存储提供器可以从NuGet中找到。其中,由官方团队维护的包有:
- Microsoft.Orleans.Persistence.AdoNet,用于SQL数据库及其他ADO.NET所支持的存储系统。详情见ADO.NET颗粒持久化。
- Microsoft.Orleans.Persistence.AzureStorage,用于Azure Blob Storage、Azure Table Storage、基于Azure Table Storage API的Azure CosmosDB等Azure Storage。详情见Azure Storage颗粒持久化。
- Microsoft.Orleans.Persistence.DynamoDB,用于Amazon DynamoDB。详情见Amazon DynamoDB Storage。
API
Grain使用IPersistentState<TState>
接口与其持久化状态进行交互,其中TState
是可序列化的状态类型:
public interface IPersistentState<TState> where TState : new()
{
TState State { get; set; }
string Etag { get; }
Task ClearStateAsync();
Task WriteStateAsync();
Task ReadStateAsync();
}
实现了IPersistentState<TState>
的实例可以通过构造器注入到Grain中。这些参数应标记上[``PersistentState(stateName, storageName)``]
特性,其中:
stateName
为被注入的状态的名字;storageName
为相应的存储提供器的名字。
以下的示例代码给上面图中UserGrain的构造器注入了两个state:
public class UserGrain : Grain, IUserGrain
{
private readonly IPersistentState<ProfileState> _profile;
private readonly IPersistentState<CartState> _cart;
public UserGrain(
[PersistentState("profile", "profileStore")] IPersistentState<ProfileState> profile,
[PersistentState("cart", "cartStore")] IPersistentState<CartState> cart,
)
{
_profile = profile;
_cart = cart;
}
}
不同的Grain类型可以使用不同配置的存储提供器,即便存储提供器类型相同:两个不同的Azure Table Storage存储提供器,可以连接的是不同的Azure Storage账户。