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

Added optional 'tag' to lifetime scope. #31

Closed wasabii closed 6 years ago

wasabii commented 6 years ago

I am always using a tag, defaulting to "ServiceFabric". This seems reasonable to me, and not unlike other Autofac extensions like MassTransit's, which default message scope to a particular value. However, I'm sure you'd rather use a constant. But I'm not sure what class you want constants like this in.

I did not alter public method signatures. Instead, I added secondary methods with an optional parameter. You might have different preferences.

alexmg commented 6 years ago

Hi @wasabii. Sorry it has taken so long to get to this.

I'm interested to know what services you are registering in the tagged lifetime scope. We used to use them a lot in earlier integrations (MVC, Web API etc.) but their use tended to cause a lot of confusion. The question about how to reuse services in a different context (such as outside of the web application) would come up regularly. I certainly understand the benefits myself.

We could add an extension method like InstancePerServiceFabricService that registers a service with a known tag and always use that tag when creating the lifetime scope. Any one else using InstancePerLifetimeScope should not be affected by the lifetime scope being created with a tag.

wasabii commented 6 years ago

Hah. Thanks for the reply. I'm trying to remember what made me do this.

wasabii commented 6 years ago

Can't remember the specifics that I was working on then. But I think it had to do with only having certain components that would activate for certain Service types. Since SF supports running multiple service instances (of differnet types) within the same EXE (Shared not Exclusive), and registering them all from the same container, it was useful to mark certain dependencies that are available only for certain service types.

For instance, you an run two different Kestrel apps inside the same EXE. You just register two Startup classes. However, each one ends up trying to find IHostedService within the container, resulting in each running all services.

So, I wanted to register my IHostedServices per-service. By giving them unique scope names. And then when registering each type, give them the matching scope name.

I think I was probably trying to do that!

wasabii commented 6 years ago

OH. I remember. Here's the good one: If you're running ASP.Net Core inside of Service Fabric, you get your single SF service for the WebHost. And that works inside of Autofac-SF lifetime scope. However, you start up ASP.Net inside of that, which creates YET ANOTHER SCOPE per request.

So, if you want a "singleton per service", you have no way to do it. You can mark it instance per lifetime scope: but that becomes per-request. Or you can mark it Singleton, but that becomes per-process.

There's no way to just have a single instance PER SERVICE.

RemcoBlok commented 6 years ago

I would also like to see the SF service lifetime scope tagged. I use MassTransit in my SF service and would like to share a single instance of a class between the SF service and a MassTransit consumer. Autofac.MassTransit creates its own lifetime scope for each message consumed by a MassTransit consumer. So I am unable to use InstancePerLifetimeScope, unless Autofac.SF was to tag the lifetime scope it creates for a SF service. Then I could use InstancePerMatchingLifetimeScope. Could this PR be completed please?

alexmg commented 6 years ago

@RemcoBlok That seems like a reasonable example. From memory MassTransit uses a message tag by default.

Things changed a bit since this PR was opened so I made the same changes again myself and added a couple of extra tests to ensure the default or user provided tag is used.

This change is in Autofac.ServiceFabric 2.1.0-develop-00053 on our MyGet feed (https://www.myget.org/F/autofac/api/v3/index.json). It would be awesome if you could give it a test.

RemcoBlok commented 6 years ago

Thank you for responding so quickly. Unfortunately I have been unable to see the prerelease version on your MyGet feed. I can see the 2.0.0 version. Am I missing something?

alexmg commented 6 years ago

I just checked and the Autofac.ServiceFabric 2.1.0-develop-00053 package is definitely there. You will need to check the Include prerelease option and make sure you have the right Package source selected if using Visual Studio to look for the update.