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 #1360: Unify the "no constructors found" reporting #1362

Merged
merged 5 commits into from
Jan 8, 2023
Merged

Conversation

tillig
Copy link
Member

@tillig tillig commented Jan 4, 2023

  • Removes the custom message from the ReflectionActivator and moves it to the NoConstructorsFoundException.
  • Added a required IConstructorFinder parameter to the exception to indicate what wasn't able to find constructors.
  • Stop throwing on zero constructors in DefaultConstructorFinder - let the activator handle throwing.

I fixed an analyzer finding in the benchmark tests where we can use a local function instead of Action<T>.

There are some analyzer warnings causing the build to fail in OpenGenericServiceBinder right now because the list of services gets enumerated multiple times. I'm not sure yet if it'd be better to allow that to happen (spend CPU) or if we should cast ToArray or ToList to do the enumeration once and eat the memory allocation. The source isn't from a database, so the multiple enumeration isn't really an issue from that perspective.

Let the activator handle throwing the exception when there are no
available constructors found. Enables consistent handling.
This moves the generation of the standard "no constructors found"
message to the exception rather than keeping it in the activator.
Minor fix based on analyzer recommendation.
@tillig tillig linked an issue Jan 4, 2023 that may be closed by this pull request
The caller can test whether the service is the right type, no need to
have overloads for that. Simplifies the binder class.
After running some benchmarks, the cost to re-enumerate the in-memory
collections is low compared to the cost of allocating a new list to
avoid re-enumeration.
@tillig
Copy link
Member Author

tillig commented Jan 5, 2023

I did a little benchmarking and it seemed like any CPU gain from not re-enumerating the in-memory collections of services didn't balance out with the amount of memory allocated to stop re-enumeration. On a collection of around 5000 services, re-enumeration of an in-memory list cost about 300ms, while storing the list cost about 200ms and added 50KB in memory allocation for the list. (I didn't keep the results, it wasn't that scientific, and it didn't seem worth really pushing on.)

Point being, it seemed reasonable to suppress the re-enumeration warnings in these cases until we get a chance to potentially refactor the code in question.

I did remove some overloads in the binder that didn't seem necessary. They were getting called from basically one spot each and the caller could do the work of the overloads to allow us to short-circuit a little of the logic in the binder. It probably doesn't actually save anything measurable, but it made the binder class a little smaller and more manageable.

Copy link
Member

@alistairjevans alistairjevans 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. 🚢

@tillig tillig merged commit 6654c7f into develop Jan 8, 2023
@tillig tillig deleted the feature/1360 branch January 8, 2023 16:07
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

Successfully merging this pull request may close these issues.

Inconsistent error reporting when no constructors are found
2 participants