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

Fix DI regression with FactoryCallSite #57155

Merged
5 commits merged into from
Aug 12, 2021
Merged

Conversation

maryamariyan
Copy link
Member

@maryamariyan maryamariyan commented Aug 10, 2021

This is fixing regression caused by PR refactor #52140

Helps fix regressions described in: #54170 and #56781

_realizedServices[callSite.ImplementationType] = accessor;

needs to instead be

_realizedServices[callSite.ServiceType] = accessor; 

We're addressing two bugs:

  • Fixes ArgumentNullException throwing when ImplementationType is null for factory callsites.
  • Fixes perf hit, since the cached implementation type is useless, which needs to in fact be ServiceType instead.

@ghost
Copy link

ghost commented Aug 10, 2021

Tagging subscribers to this area: @eerhardt, @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

null

Author: maryamariyan
Assignees: maryamariyan
Labels:

area-Extensions-DependencyInjection

Milestone: -

public class ServiceCollectionDescriptorExtensionsTest
{
[Fact]
internal void GetService_FactoryCallSite_Transient_DoesNotFail()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this test catch the bug you are fixing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it does

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain how? Why is DependencyInjectionEventSource.Log.ServiceRealizationFailed fired? I thought we just put the compiled accessor into the wrong slot and don't use it.

Copy link
Member Author

@maryamariyan maryamariyan Aug 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the transient service is being registered as a factory callsite, then ImplementationType will be null and will cause ArgumentNullException on

_realizedServices[callSite.ImplementationType] = accessor;

and cause Debug.Fail and that log to get fired.

cc @eerhardt

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FactoryCallSite has a null implementation type so it throws argument null here.

Copy link
Contributor

@pakrym pakrym Aug 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a pretty indirect way to test it.

We can test it more directly by registering

IService -> Service
Service -> Service

And ensuring that both accessors return distinct values.

What I don't understand is don't we already have a test that uses a transient factory using a dynamic service provider? Or is the problem that we don't actually get to compile it in those tests?

Should we add a mode that uses the dynamic engine but forces the compilation eagerly and run all tests through it? Otherwise, we would keep adding more variations of existing tests with for and Thread.Sleep in them

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I'll check where these similar tests are. I updated the PR description to describe the two scenarios being fixed here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a test that does the two above registrations with transient lifetime and using factory callsite, kicks off background thread and after the fix Debug.Fail, won't hit anymore.

@maryamariyan
Copy link
Member Author

@eerhardt @davidfowl @pakrym ready for another review. I think all comments are addressed

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks!

@ghost
Copy link

ghost commented Aug 11, 2021

Hello @maryamariyan!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 7983648 into dotnet:main Aug 12, 2021
@maryamariyan maryamariyan deleted the regression-di branch August 12, 2021 02:52
@kunalspathak
Copy link
Member

Improvements: dotnet/perf-autofiling-issues#607

@kunalspathak
Copy link
Member

Improvements: dotnet/perf-autofiling-issues#566

@kunalspathak
Copy link
Member

kunalspathak commented Aug 19, 2021

Improvements in arm64: dotnet/perf-autofiling-issues#620, dotnet/perf-autofiling-issues#627

@ghost ghost locked as resolved and limited conversation to collaborators Sep 18, 2021
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants