castleproject / Core

Castle Core, including Castle DynamicProxy, Logging Services and DictionaryAdapter
http://www.castleproject.org/
Other
2.2k stars 468 forks source link

[Help] I can't use Castle for proxy internal class #686

Open Dragon-0609 opened 2 weeks ago

Dragon-0609 commented 2 weeks ago

Hi. I have an internal class in another assemly.

internal class StatusBar : View

I want to override it's protected override void OnDisplay(), but, for some reason my code doesn't work.

Here's my code

private static void Hook(Type targetType, object instance ){
    ProxyGenerator generator = new ProxyGenerator();

    var proxy = generator.CreateClassProxyWithTarget(
        targetType, // The type of the class to proxy
        instance, // The instance of the internal class
        new OnDisplayInterceptor() // Our interceptor to handle the method call
    );
    var methodInfo = proxy.GetType().GetMethod("OnDisplay", BindingFlags.NonPublic | BindingFlags.Instance);
    methodInfo.Invoke(proxy, null); // Call the method via reflection
}

public class OnDisplayInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Before OnDisplay");

        invocation.Proceed();

        Console.WriteLine("Updated OnDisplay");
    }
}

Before OnDisplay is printed, but invocation.Proceed doesn't work. It gives null reference. Do you know in where I wrote wrong?

stakx commented 2 weeks ago

You'd be better off asking plain usage questions on places such as Stack Overflow; this GitHub issue tracker focuses on the development of this library.

Even if this were a bug, your code example is incomplete – you've not included the relevant method of the proxied type.

All of that being said, I'm assuming the problem here might be a missing assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)] attribute in the assmbly that first declared View.OnDisplay. Have you tried adding that attribute to your assembly and overriding that method in your derived class?

Dragon-0609 commented 2 weeks ago

the problem here might be a missing assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)] attribute in the assmbly that first declared View.OnDisplay

If I had access to change the library, I would have directly inherited the class itself and override it.

Even if this were a bug, your code example is incomplete – you've not included the relevant method of the proxied type.

What's the relevant method of the proxied type? I asked Chat GPT to help me with my problem and it suggested the code similar to above

stakx commented 2 weeks ago

The "relevant method of the proxied type" is the one you are interested in. (I'm guessing View.OnDisplay but I cannot be sure since your repro code above is incomplete.)

Dragon-0609 commented 2 weeks ago

Do you need full code of View.OnDisplay?

stakx commented 2 weeks ago

Anyhow, we can leave this issue open for a while, in case someone else wants to chime in and offer help; otherwise I'll close it in a few weeks or so.

Dragon-0609 commented 2 weeks ago

Ok, thanks for your reply. In case you asked is the method virtual or abstract, it's virtual. Here's the definition from View:

    protected virtual void OnDisplay()
    {
    }
stakx commented 2 weeks ago

Do you need full code of View.OnDisplay?

No, not necessarily. If you seek help online, you should show just enough of your code such that it can be compiled and executed successfully while still exhibiting the problem that you're asking about... don't just drop all of your code without making any attempt to remove all irrelevant bits first... do try to come up with a minimal repro. (The Stack Overflow community used to call that a minimally complete and verifiable code example.)