Closed wasabii closed 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.
Hah. Thanks for the reply. I'm trying to remember what made me do this.
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!
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.
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?
@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.
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?
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.
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.