Question

I have an application that loads plugins. I have a plugin that has complete access to a form instance. If I have a function in a form that needs to be overridden, but is not a virtual function, is there another way to override it?

Here is a very generic example:

//Form I am modifying
public partial class MyForm : Form
{
    public int myVariable1;
    public int myVariable2;

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        myVariable1 = replacementValue;
    }
}

...then in a separate dll...

//My plugin
public class MyPlugin : IMyPluginBase
{
    MyForm theForm; //Reference to the form in the main application

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        theForm.myVariable2 = replacementValue;
    }
}

In this example the function in the form sets 'myVariable1', but the 'setVar' function in the plugin sets 'myVariable2'.

So, the question is, in the case of this example, can I replace/override the form's 'setVar' function with the one in the plugin? Maybe with messages or reflection?

Was it helpful?

Solution

No. You cannot "replace" or overide private non-virtual methods in C#.

The C# language (and .NET runtime) don't support dynamic replacement of methods in the manner you describe. Very few languages support this capability, to my knowledge (I believe that SmallTalk and Objective-C both do).

If this is the only place in your application where you need this kind of extensibility, you can achieve it through an interface, delegate, or inhertance+virtual methods. Any of these approaches could work ... which one you choose depends on what kind of extensibility you desire.

If you expect to have many such extensibility points in your app, then you should probably take a look at the Managed Extensibility Framework (MEF). It provides a Microsoft-supported model for creating plug-in architectures using patterns and technique that work well in .NET.

OTHER TIPS

If a function is not marked as virtual or part of an interface that your class implements there's exactly 0 chance you would be able to override it. No plugin, no reflection, no nothing, simply forget about it or use some other dynamic language but not C#.

The short answer to your question is no. What you can do, however, is give your form a copy of the IMyPluginBase, and have Form.setVar() call out to MyPluginBase.SetVar().

The code will look something like this:

public partial class MyForm : Form
{
    public int myVariable1;
    public int myVariable2;

    public IMyPluginBase MyPlugin;

    //Constructor and other methods here

    private void setVar(int replacementValue)
    {
        MyPlugin.setVar(replacementValue);
        //myVariable1 = replacementValue;
    }
}

public class MyPlugin : IMyPluginBase
{
    MyForm theForm; //Reference to the form in the main application
    public void setVar(int replacementValue)
    {
        theForm.myVariable2 = replacementValue;
    }
}

Note that setVar() will need to be defined in IMyPluginBase.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top