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 wrong type being passed to IInterceptorSelector.SelectInterceptors for class proxies #359

Merged
merged 3 commits into from
May 30, 2018

Conversation

stakx
Copy link
Member

@stakx stakx commented May 26, 2018

This resolves #74.

Copy link
Member Author

@stakx stakx left a 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,
Copy link
Member Author

@stakx stakx May 26, 2018

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.

private readonly Reference interceptors;
private readonly Type invocation;

public MethodWithInvocationGenerator(MetaMethod method, Reference interceptors, Type invocation,
GetTargetExpressionDelegate getTargetExpression,
OverrideMethodDelegate createMethod, IInvocationCreationContributor contributor)
: this(method, interceptors, invocation, getTargetExpression, null, createMethod, contributor)
{
}
Copy link
Member Author

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.

Copy link
Member

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.

@stakx stakx force-pushed the issue-74 branch 2 times, most recently from e786159 to 7f55def Compare May 27, 2018 08:50
stakx added 3 commits May 30, 2018 15:00
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.
Copy link
Member

@jonorossi jonorossi left a 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.

@jonorossi jonorossi merged commit 98b37bc into castleproject:master May 30, 2018
@jonorossi jonorossi added this to the vNext milestone May 30, 2018
@stakx stakx deleted the issue-74 branch May 30, 2018 17:11
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.

Interceptor Selectors under CreateClassProxy are provided a System.RuntimeType rather than a System.Type
2 participants