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

Dependency injection with convenience methods #6783

Closed
breyed opened this issue Jun 1, 2018 — with docs.microsoft.com · 7 comments
Closed

Dependency injection with convenience methods #6783

breyed opened this issue Jun 1, 2018 — with docs.microsoft.com · 7 comments
Assignees
Labels
Pri2 Source - Docs.ms Docs Customer feedback via GitHub Issue

Comments

Copy link
Contributor

breyed commented Jun 1, 2018

Using the convenience methods, how can I access services such as ILoggerFactory provided by the hosting service? Using Startup, they are available via dependency injection in the constructor and Configure. What is the equivalent for the convenience methods?


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

@guardrex guardrex self-assigned this Jun 1, 2018
@guardrex guardrex added Pri2 Source - Docs.ms Docs Customer feedback via GitHub Issue labels Jun 1, 2018
@guardrex guardrex added this to the Backlog milestone Jun 1, 2018
@Tratcher
Copy link
Member

Tratcher commented Jun 1, 2018

@guardrex that doesn't really answer the question, it bypasses DI altogether.

There's no direct way to get services into ConfigureServices. There are some indirect ways where you register your thing that needs a service as its own service and then resolve it later outside of ConfigureServices. People sometimes do this with IConfigureOptions.

In Configure you can call IApplicationBuilder.ApplicationServices.GetRequiredService<T>(). That might be worth providing an example for.

@guardrex
Copy link
Collaborator

guardrex commented Jun 1, 2018

provided by the hosting service

Yes. I understand. @breyed You're looking for more than a hack to get a console logger?

call IApplicationBuilder.ApplicationServices.GetRequiredService<T>(). That might be worth providing an example for.

Sounds good. I'll pitch a PR for that ... when I can. 🏃😅

@Tratcher
Copy link
Member

Tratcher commented Jun 1, 2018

Interesting point: IWebHostBuilder.ConfigureServices is not equivalent to Startup.ConfigureServices. IWebHostBuilder.ConfigureServices is called first and adds services to the host's DI container. That's why no DI services are available at this stage. Startup.ctor can consume the host's services and then Startup.ConfigureServices builds a secondary container.

@davidfowl
Copy link
Member

It's a chicken and egg problem. You need a container to activate the Startup class so we have a bootstrapping container for this reason. When you're not using Startup there's nothing to activate and thus no way to get services. We don't have a ConfigureApplicationServices on WebHostBuilder which would be the equivalent of what Startup offers today.

@guardrex
Copy link
Collaborator

guardrex commented Jun 1, 2018

Startup.ctor can consume the host's services and then Startup.ConfigureServices builds a secondary container.

Which means that we can expand our example for Startup to show an ILoggerFactory going into the ctor there for a Startup class logger. That's probably a good idea for that scenario. [EDIT] Works fine. This will be a good add there I think.

Otherwise for the convenience methods, I'll just pitch that example with GetRequiredService in Configure.

@breyed
Copy link
Contributor Author

breyed commented Jun 1, 2018

FWIW, the reason this question even arose for me is not because I wanted to log the startup process. Rather, in ConfigureServices, in my AddMvc, I was replacing ComplexTypeModelBinderProvider with a custom binder provider that derives from it, with the added functionality of trimming whitespace.

This was all well and good (at least it worked - I can't say whether it was the best approach) until ASP.NET Core 2.1, when the ComplexTypeModelBinder constructor that doesn't take an ILoggerFactory parameter was deprecated. Hence my desire to access ILoggerFactory from ConfigureServices.

Based on the discussion here and in aspnet/Hosting#1150, it seems like ConfigureServices comes too early to access the logging service that will be used when model binding occurs. Not knowing how this is supposed be get hooked up, I decided to punt with a #pragma warning wrapper, but I thought I'd throw this out there in case it spurs any thoughts on the proper way to handle the situation.

@blyndcide
Copy link

Same problem here. I want to add

services.AddMvc(options => { ... options.Filters.Add(new ResponseCacheFilter(new CacheProfile() { Location = ResponseCacheLocation.None, NoStore = true, Duration = 0 }, //how to get ILoggerFactory?)); ... })

There is no longer a ResponseCacheFilter constructor that doesn't require an ILoggerFactory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Pri2 Source - Docs.ms Docs Customer feedback via GitHub Issue
Projects
None yet
Development

No branches or pull requests

5 participants