-
Notifications
You must be signed in to change notification settings - Fork 483
Fix wrong type being passed to IInterceptorSelector.SelectInterceptors for class proxies
#359
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
Conversation
stakx
left a comment
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.
Just a couple of explanatory notes.
| new MethodInvocationExpression(null, | ||
| TypeUtilMethods.GetTypeOrNull, | ||
| getTargetExpression(@class, MethodToOverride)), | ||
| targetTypeExpression, |
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.
The simplest possible bugfix (which wouldn't require any changes in locations other than this one) would be to wrap the result of getTargetExpression(...) with a call to TypeUtil.GetTypeOrNull only if it is not a TypeTokenExpression already. I discarded this simpler solution because it feels like a hack. (It requires out-of-band knowledge about the kind of Expression that class proxies will produce inside their version of getTargetExpression.) The fix proposed in this PR is more elaborate, but arguably cleaner.
| OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor) | ||
| : this(method, interceptors, invocation, getTargetExpression, null, createMethod, contributor) | ||
| { | ||
| } |
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.
Adding the new parameter to the existing (publicly visible) ctor would be a breaking change, hence a new ctor.
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.
No one should be using these classes anyway as they really are internal implementation, but happy for this to stay as is for now and can be removed later.
e786159 to
7f55def
Compare
These verify that the `type` argument passed to `SelectInterceptors` is equal to the type of the proxy's target. (There are also tests for `IInvocation.TargetType` in order to ensure consistency between `IInvocation` and `IInterceptorSelector`.) One of these tests will fail: When a proxy is created using `Create- ClassProxy`, `SelectInterceptors` will receive a `type` representing `System.RuntimeType` instead of the target's type.
This is achieved by the following three measures:
1. Fix the incorrect XML documentation for the `type` parameter of
`IInterceptorSelector.SelectInterceptors`. This parameter receives
the target type, *not* the intercepted method's declaring type.
2. Add a new ctor to `MethodWithInvocationGenerator` that accepts an
additional parameter `getTargetTypeExpression` (next to `get-
TargetExpression`) to account for the fact that invocation classes
sometimes require a target object (e.g. `CompositionInvocation`)
while others require a target type (e.g. `InheritanceInvocation`).
The new parameter is optional; if `getTargetTypeExpression` is not
provided, the target type is derived from the target object.
3. Use the new constructor for class proxies. We do *not* want to
have the target type derived from the target object, because that
would make the dynamically generated proxy type visible. (For
class proxies, the target object and the proxy object are one and
the same). Instead we want the target type to be the proxied type.
jonorossi
left a comment
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.
Looks great, thanks for getting that fixed.
This resolves #74.