-
-
Notifications
You must be signed in to change notification settings - Fork 802
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
.CallBase
for default interface implementations
#1130
Merged
stakx
merged 5 commits into
devlooped:main
from
stakx:default-interface-implementations
Jan 17, 2021
Merged
.CallBase
for default interface implementations
#1130
stakx
merged 5 commits into
devlooped:main
from
stakx:default-interface-implementations
Jan 17, 2021
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
stakx
commented
Jan 16, 2021
// Put the return value in a local variable for later retrieval. | ||
if (method.ReturnType != typeof(void)) | ||
{ | ||
il.Emit(OpCodes.Box, method.ReturnType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would fail on a by-ref return type (which AFAIK neither we nor DynamicProxy currently support anyway).
stakx
force-pushed
the
default-interface-implementations
branch
from
January 17, 2021 03:14
b1f2a0b
to
e2c4a27
Compare
stakx
force-pushed
the
default-interface-implementations
branch
from
January 17, 2021 03:16
e2c4a27
to
72db581
Compare
* We don't really need two new classes for the helper methods. Define those directly inside `CastleProxyFactory`. * Rename methods and change their signatures so `Invocation.CallBase` in `CastleProxyFactory` reads a little more clearly. * Add some more explanation comments to the code.
stakx
force-pushed
the
default-interface-implementations
branch
from
January 17, 2021 10:42
72db581
to
3f54703
Compare
This was referenced Mar 12, 2021
mburumaxwell
pushed a commit
to faluapp/falu-dotnet
that referenced
this pull request
Jun 12, 2021
Bumps [Moq](https://github.com/moq/moq4) from 4.16.0 to 4.16.1. #Changelog *Sourced from [Moq's changelog](https://github.com/moq/moq4/blob/main/CHANGELOG.md).* > ## 4.16.1 (2021-02-23) > > #### Added > > * `CallBase` can now be used with interface methods that have a default interface implementation. It will call [the most specific override](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods#the-most-specific-override-rule). (@stakx, [#1130](devlooped/moq#1130)) > > #### Changed > > * Improved error message formatting of `It.Is` lambda expressions that capture local variables. (@bfriesen, [#1140](devlooped/moq#1140)) > > #### Fixed > > * `AmbiguousMatchException` raised when interface has property indexer besides property in VB. (@mujdatdinc, [#1129](devlooped/moq#1129)) > * Interface default methods are ignored (@hahn-kev, [#972](devlooped/moq#972)) > * Callback validation too strict when setting up a task's `.Result` property (@stakx, [#1132](devlooped/moq#1132)) > * `setup.Returns(InvocationFunc)` wraps thrown exceptions in `TargetInvocationException` (@stakx, [#1141](devlooped/moq#1141)) #Commits - [`fc484fb`](devlooped/moq@fc484fb) Update version to 4.16.1 - [`0ddfdb8`](devlooped/moq@0ddfdb8) `Returns(InvocationFunc)` shouldn't throw `TargetInvocationException` - [`f36d3e8`](devlooped/moq@f36d3e8) Merge pull request [#1140](devlooped/moq#1140) from bfriesen/lambda_closure_support - [`e96804f`](devlooped/moq@e96804f) Update the changelog - [`5ae449c`](devlooped/moq@5ae449c) Exclude name of the closure class - [`8a2d2ed`](devlooped/moq@8a2d2ed) Add test for closure access - [`cf5af87`](devlooped/moq@cf5af87) Format lambda expression variables - [`5b10a8c`](devlooped/moq@5b10a8c) Add test for lamba matcher variables - [`653db31`](devlooped/moq@653db31) Some minor renames for consistency - [`fc73131`](devlooped/moq@fc73131) Add missing copyright notices - Additional commits viewable in [compare view](devlooped/moq@v4.16.0...v4.16.1)
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As of version 4.4.0, DynamicProxy is not able to reliably
.Proceed()
to a base method implementation if it is provided by an interface. From a user perspective, one would likely try to invoke a default interface implementation using.CallBase()
.This is an attempt to work around this current DynamicProxy limitation by performing the non-virtual call to the interface method manually. This involves some System.Reflection.Emit code inspired by @thomaslevesque's approach mentioned in castleproject/Core#447 (comment).
This works mostly, except for one important detail: Moq will always call the least specific default implementation, instead of the most specific one. (This matters when one overrides a default implementation in a derived interface, then mocks that derived interface or a type inheriting/implementing it.)(Update: Most specific override identification is now implemented, too.)The code being added here is rather horrible, and it would be very good to get rid of it as soon as DynamicProxy properly supports proceeding to default interface implementations.
Resolves #972.