dotnet / orleans

Cloud Native application framework for .NET
https://docs.microsoft.com/dotnet/orleans
MIT License
10.07k stars 2.03k forks source link

Access to declared state type in IGrainStorage #4910

Closed alirezajm closed 5 years ago

alirezajm commented 6 years ago

The declared type of the grain state is not accessible via IGrainState. The runtime type is, however, you can't determine the actual declared type. This causes problems when the state is of a derived type of the declared type. e.g. in the IGrainStorage interface, the only params you get about the state is IGrainState and if you need the declared type you're out of luck.

There's a hack available though. The implementation type of IGrainState is the internal GrainState<>. so it is possible to extract the state type but it's not pretty. something like this:

Type declaredStateType = grainState.GetType().GenericTypeArguments[0]

and hope the grainState runtime type doesn't change.

I can suggest two options: 1 - Add DeclaredStateType parameter to IGrainStorage methods. 2 - Add DeclaredStateType to IGrainState. This does make the grain state object bigger, and I don't know other places using IGrainState. So if there's no benefit other than this I would stay with the hack or give it a second thought.

alirezajm commented 6 years ago

@xiazen any word on this?

xiazen commented 6 years ago

If I understand correctly, you want the IGrainState to contain the declared type. This confused me a bit, Grain<T> means the state type is T, which is the declared type? This means grain code (application code) should know the declared type, why does IGrainState needs to provide that?

xiazen commented 6 years ago

You mentioned the IGrainStorage case, where from the interface of IGrainStorage, it only have access to IGrainState, so that IGrainStorage doesn't know IGrainState declared type. Is this the only case that is bothering you? can you elaborate more on what you want to do with decleared IGrainState type in IGrainStorage?

alirezajm commented 6 years ago

Well yes my primary concern is implementing the IGrainStorage.

I'm using Entity Framework for storage so I need to know the declared type of the grain state ( ef contexts are type safe and preconfigured)

In the following method in IGrainStorage

Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)

I have two options to extract the declared type:

Actually I don't like my suggestions really. But at the same time I wasn't happy about the hack so I thought I raise the issue.

xiazen commented 5 years ago

Hi sorry for the late reply.

Yes by currently design of IGrainStorage, it doesn't care about grain state type at the storage level. For your use case, it maybe faster to create a custom grain storage for your application.

We introduced "facet" in 2.0, as a easy way to add extensible points to Orleans. I think you can use that to create your custom grain state storage faster, instead of using the old way to create a custom grain state storage. Take a look at StorageFacetGrain in your Tester.csproj, you will have a better understanding of facet. That grain has a custom storage facet called ExampleStorage

Unfortunately we didn't got time to add documentation for facet yet. But do reach out for questions!

alirezajm commented 5 years ago

Thanks I'll take a look it 👍