Open VladimirSmall opened 5 years ago
Sorry I was wrong in my previous comment. In your case, it looks the change is not a bug, but by design. The interceptor only wants to intercept all public
methods, and own family (protected
) methods. You should add an interception registration for Base
class' ProtectedVirtualMethod
.
Was closed by my mistake
You should add an interception registration for Base class' ProtectedVirtualMethod.
Thank you for your advice, but it doesn't work. This test fails.
[Fact]
public void ShouldAbleInterceptBaseClassProtectedVirtualMethods()
{
var container = new ServiceContainer();
container.Register<Derived>();
var interceptor = new ProtectedVirtualMethodInterceptor();
container.Intercept(
sr => typeof(Derived).IsAssignableFrom(sr.ServiceType),
(r, d) => d.Implement(() => interceptor, m => m.Name == "ProtectedVirtualMethod"));
container.Intercept(
sr => typeof(Base).IsAssignableFrom(sr.ServiceType),
(r, d) => d.Implement(() => interceptor, m => m.Name == "ProtectedVirtualMethod"));
var instance = container.GetInstance<Derived>();
instance.Call();
Assert.True(interceptor.IsInvoked);
}
The interceptor only wants to intercept all public methods, and own family (protected) methods.
Why we should be limited to own protected methods only? Why we couldn't intercept base class protected virtual methods? Your own library LightInject.SignalR based on interception of base class virtual protected method HubBase.Dispose(bool) too. If you will port LightInject.SignalR to support new LightInject and LightInject.Interception you will see that LightInject.SignalR support was broken - interceptor for base class Dispose(bool) method is never called.
You could fix this issue simply by replacing in method MethodSelector.Execute
targetType.GetRuntimeMethods().Where(m => m.IsPublic).
with
targetType.GetRuntimeMethods().Where(m => m.IsPublic || (m.IsFamily && !m.IsDeclaredBy<object>())).
If needed i can create pull request to fix the issue.
The following test fails.
It's interesting that the same test with Base class instead of Derived succeeds.
Little investigation showed that test works with version 1.2.1, but does not wrok with version 2.0.0 of LightInject.Interception.
The reason in method MethodSelector.Execute code. It was
But in revision 544c1c7c7600d46402195a022073653b2cfd2958 it was changed to.
targetType.GetTypeInfo().DeclaredMethods does not include base class methods. This brokes LightInject.SignalR support - it based on interception of virtual protected method Hub.Dispose(bool), which belongs to HubBase class.