-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Native dependency injection #3057
Conversation
This will need to go into a feature branch, not |
b4093ec
to
1a6d606
Compare
878c287
to
f6eea05
Compare
Missing parts:
This last thing is the most troublesome - from what I've understood
|
@Horusiath how come this PR was abandoned? (I arrived here via #1675) |
@stijnherreman it's not abandoned - it just moved to #3862 |
As proposed in #3050, this is a reference work-in-progress example of how we could replace existing actor creation pipeline and expose it to provide native support for dependency injection. I've used
Microsoft.Extensions.DependencyInjection
here, the same lib which is used in ASP.NET Core - this also means, that we can reuse DI mechanics between those two.In general, there are multitude of places, where DI could be used - potentially almost every place where
Activator.CreateInstance
is used right now, except hot paths. There should be a way to create an actor in two ways, both fast using explicit construction and with dependency injection. Here's how:Props.Create(() => new Actor(args))
is explicitly describing how actor should be created, there's no need for DI here. This is a fast lane.Props.Create<Actor>()
doesn't provide any details about construction mechanics, therefore it could be injected.I was thinking about the place where custom user services could be registered, since we don't have equivalent of
Startup
class that could be used to configure services from code. However my idea was to add extra method to anvoid IExtension.ConfigureServices(IServiceCollection)
- this way when someone would get an extension like Cluster, Persistence etc. it would register all necessary dependencies inside.IExtension
s themselves could be resolved using DI - this would simplify API of this interface (no longer need forExtensionIdProvider<>
orIExtension.Get
/Apply
etc. methods. It also encourages users to define their own business rules as akka extensions, which is actually a good pattern. I'm not sure if this library API will allow us to do so, but I'm pretty optimistic here.Microsoft.Extensions.DependencyInjection
introduces 3 lifetime scopes:Singleton
- in our case ActorSystem.Transient
- a particular incarnation of an actor, created each time an actor constructor is called.Scoped
- anIActorContext
scope. Shared between incarnations as described bellow.The extra stuff I added to an
ActorCell
itself isIScope
interface. Motivation is here: whileProps
are working as a descriptors of how actors of particular type should be constructed, there is no primitive that would tell how to create an actor in the context of a particular actor context. This is where scope comes in.While actors created with
Props.Create(() => new Actor())
are defined explicitly, the scope for them is essentially the same thing as Props: we want to keep them fast. However actors created dynamically, potentially with help of dependency injection, have custom scopes assigned to anActorCell
itself. This means thatServiceLifetime.Scoped
object lifetime is equal to that of actor cell, not an actor incarnation itself.