Skip to content
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

Override ISolrOperations dependency injection lifetime #615

Open
gdau opened this issue Jun 12, 2023 · 3 comments
Open

Override ISolrOperations dependency injection lifetime #615

gdau opened this issue Jun 12, 2023 · 3 comments

Comments

@gdau
Copy link

gdau commented Jun 12, 2023

Hi,

I am attempting to consume the solr API from a IHostedService implementation (i.e. outside of a web application - this console application will maintain the search index).

As per the instructions, I am registering the necessary dependencies with this built-in call during ConfigureServices:

services.AddSolrNet("mysearch");

which internally registers the ISolrOperations<> type as having Scoped lifetime. This is fine for a web application where the scope is generally tied to the request lifetime but it does create issues when trying to inject my class which has a dependency on ISolrOperations into the IHostedService (since IHostedService has a lifetime of Singleton by default).

I have gotten around this by adding this line straight after the registration above which effectively replaces the Scoped lifetime with a Transient lifetime.

services.AddTransient(typeof(ISolrOperations<>), typeof(SolrInjectionServer<>));

Is there any particular reason why the lifetime is set to scoped and would there be any side-effects of making it transient or singleton? Would it be possible to override this behaviour in future?

Thank you!

g

@mausch
Copy link
Member

mausch commented Jun 12, 2023

Hi, I'm curious what issues does this cause?

@gdau
Copy link
Author

gdau commented Jun 12, 2023

Hi, I'm curious what issues does this cause?

Do you mean what issues does it cause if you don't use my workaround?

There is a DI exception raised immediately during startup of the console application because you cannot inject a scoped service into a service with a singleton lifetime. The pattern to get around this is to inject a IServiceProvider and create a scope inside the singleton but I'm not in control of the hosting service and it seems like it's a waste of time if I could rather just change the lifetime of the solr service without any side-effects.

@mausch
Copy link
Member

mausch commented Jul 9, 2023

Ah yeah, I forget the MS container throws in that situation.
You can easily just change service lifetimes... something like this should work:

        static void MakeSolrNetTransient(IServiceCollection services)
        {
            var solrNetServices = services
                .Where(s => s.ServiceType.Namespace.StartsWith("SolrNet"))
                .Where(s => s.ImplementationInstance == null)
                .ToList();
            foreach (var service in solrNetServices)
            {
                services.Remove(service);
                if (service.ImplementationFactory != null)
                {
                    services.Add(ServiceDescriptor.Transient(service.ServiceType, service.ImplementationFactory));
                } else if (service.ImplementationType != null)
                {
                    services.Add(ServiceDescriptor.Transient(service.ServiceType, service.ImplementationType));
                }
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants