autofac / Autofac.ServiceFabric

Autofac integration for Azure Service Fabric. Provides service factory implementations for Actors, Stateful Services and Stateless Services.
MIT License
26 stars 27 forks source link

Lifetime scope for Actor instance #45

Closed Flern closed 6 years ago

Flern commented 6 years ago

I'm struggling with service resolution for my Actors. I have a command handler pattern that resolves ICommandHandler generic handlers, and I have a repository service that the command handlers use. When I route the command to all the handlers, they use that repository service to store the results in a queue. I configured the repository service as a SingleInstance such that the higher-level Actor method and the generic command handlers would all be using the same instance.

I found out during integration that the SingleInstance lifetime for an Actor service is the entire service - i.e., each Actor instance created during the runtime is using the same repository with a queue intended to serve only one Actor instance. Because of the pattern of generic command handler resolution, I don't think the faux-per-request lifetime scope approach will work for me, but I am really hoping I'm wrong about that.

How would I go about having a shared singleton-like dependency registered within the scope of an Actor instance?

I can provide some sample code if that helps.

Flern commented 6 years ago

Ah, I figured it out.

Looking at the Introductory Blog Post, I saw this:

internal sealed class ActorFactoryRegistration : IActorFactoryRegistration
{
    public void RegisterActorFactory<TActor>(ILifetimeScope container) where TActor : ActorBase
    {
        ActorRuntime.RegisterActorAsync<TActor>((context, actorTypeInfo) =>
        {
            return new ActorService(context, actorTypeInfo, (actorService, actorId) =>
            {
                var lifetimeScope = container.BeginLifetimeScope();
                var actor = lifetimeScope.Resolve<TActor>(
                    TypedParameter.From(actorService),
                    TypedParameter.From(actorId));
                return actor;
            });
        }).GetAwaiter().GetResult();
    }
}

Therefore, the builder.RegisterType<MyConcreteType>.As<IMyServiceType>().InstancePerLifetimeScope() binds the instance to the Actor instance lifetime scope.

I'm very new to DI / Autofac - sorry about the WOB here. Keep up the good work!

alexmg commented 6 years ago

No problem @Flern. I'm glad you figured it out. Sorry I didn't get to your question sooner.