Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Configuring application parts from multiple assemblies #7287

Unanswered
freever asked this question in Q&A
Discussion options

I want to be able to have a base grain class in one assembly and subclass it in another.

For example, let's say there is shared assembly with the following:

public interface IUserGrain : IGrainWithGuidKey { }
public abstract class BaseUserGrain : Grain, IUserGrain { }

In another project I want to extend this grain to do more things.

public interface IMyUserGrain : IUserGrain { }
public class MyUserGrain : BaseUserGrain, IMyUserGrain { }

There is other code in the shared assembly that needs to reference the IUserGrain interface, and code in my assembly that needs to reference the IMyUserGrain interface to access the additional functionality, but I obviously want them to reach the same underlying Grain.

Using dependency injection I would do something like:

services.AddSingleton<IMyUserGrain, MyUserGrain>();
services.AddSingleton<IUserGrain>(sp => sp.GetService<IMyUserGrain>())

Through much trial and error I have found a way that seems to work. By hiding the base class grain in a separate assembly and only including the base interfaces (in their own assembly):

siloBuilder.ConfigureApplicationParts(parts =>
{
    parts.AddApplicationPart(typeof(MyUserGrain).Assembly);
    parts.AddApplicationPart(typeof(IMyUserGrain).Assembly);
    parts.AddApplicationPart(typeof(IUserGrain).Assembly);
})

However I am unsure if this will create one or two instances of MyUserGrain - if there are two it's a bit of a non-starter.

Does anyone know if this approach is valid, and if there is a better way that is more aligned with the IServiceCollection approach?

You must be logged in to vote

Replies: 2 comments · 2 replies

Comment options

I don't believe you need to/should even add the grain to IServiceCollection, as each grain has a primary key and theres no way to specify that primary key without using some kind of custom resolver. The orleans way is to get the grain from the IGrainFactory or IClusterClient.

As far as your application parts, it appears correct however you do have both duplicate assembly referenced for MyUserGrain and IMyUserGrain, not sure if Orleans filters out additional ones.

You can also add parts from app domain

siloBuilder.ConfigureApplicationParts(parts => parts.AddFromAppDomain())
You must be logged in to vote
2 replies
@freever
Comment options

@jbockle Yeah I am not trying to add Grains to the ServiceCollection, I was just using that as an example. When registering types with IServiceCollection you can specify which implementation should be resolved for which interface, and you can also specify that an interface should be resolved with an implementation that is already registered (thus allowing the same concrete instance to be resolved for two different interfaces). With Orleans it seems you can only register Assemblies, so you have a much blunter instrument than you do when using dependency injection.

@jbockle
Comment options

if you want to have multiple implementations of a grain interface, you have to know which implementation you want to resolve from the IGrainFactory/IClusterClient using the GetGrain optional parameter grainClassNamePrefix, which is the qualified name of the grain class

var myUserGrain = GrainFactory.GetGrain<IUserGrain>("foo-user", "SomeAssembly.Grains.MyUserGrain");

However, since IMyUserGrain is inheriting from IUserGrain, you could just resolve that type (assuming you only have only one implementation of IMyUserGrain interface)

var myUserGrain = GrainFactory.GetGrain<IMyUserGrain>("foo-user");
Comment options

application parts does not exist in leates version of Orleans.Runtime 3.7.2

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.