none
Method does not have an implementation. RRS feed

  • Question

  • I am trying to create a plugin for a custom application. One of the classes the plugin inherits an Interface in the application's base class.  The other class inherits the main form of the application so it can access all the properties and objects.  I keep getting an error saying my Initialize method of the Interface inherited class has no implementation.  In that class I make a reference to the other plugin class that inherits the application's main form.  Does anyone know why I would be getting this error?
    Patrick Mallahan
    Wednesday, June 24, 2009 9:54 PM

Answers

All replies

  • Your description of the problem is too confusing.  Post code.

    Hans Passant.
    Thursday, June 25, 2009 12:44 AM
    Moderator
  • Your description of the problem is too confusing.  Post code.

    Hans Passant.
    The code is rather large so I will try to explain in a different way.

    I have the following base clases:

    interface IReport
    {
    public Initialize();
    }

    public frmReminder : Forms
    {

    }

    In frmReminder I actually do my late binding in the _Load method/event.  My plugin dll looks like this:

    public class NewReports : IReports
    {
    Create and populate objects
    Create and access my NewReminder object
    }

    public class NewReminder : frmReminder
    {
    Code that overrides my frmReminder methods
    }


    I had tested the late binding without the second class, NewReminder and had no problems.  When I added the NewReminder class it started throwing a ReflectionTypeLoadException saying that the Initilize method in my NewReports doesn't have implementation.

    Patrick Mallahan
    Thursday, June 25, 2009 3:04 PM
  • The other thing too, both projects are contained inside the same solution if that matters.
    Patrick Mallahan
    Thursday, June 25, 2009 5:46 PM
  • Both projects?  You'll need at least 3.  One project must be a small one that declares the interfaces, IReports at least.  That assembly must be referenced by the two other ones.  This ensures that the projects always use the exact same interface type.  Getting this wrong does indeed cause the kind of exception you're getting.

    Hans Passant.
    Thursday, June 25, 2009 6:00 PM
    Moderator
  • Both projects?  You'll need at least 3.  One project must be a small one that declares the interfaces, IReports at least.  That assembly must be referenced by the two other ones.  This ensures that the projects always use the exact same interface type.  Getting this wrong does indeed cause the kind of exception you're getting.

    Hans Passant.
    They are, I am sorry. I have a base class that the interface is in and then a DLL project and a Windows Forms project.
    Patrick Mallahan
    Thursday, June 25, 2009 6:39 PM
  • A base class?  That's not an assembly.  I don't think I can help you, good luck with it.

    Hans Passant.
    Thursday, June 25, 2009 7:04 PM
    Moderator
  • Evidica, if your code is too large, then try to make it smaller ... by deleting big chunks of code from it and rebuilding it on the way (and making sure that you are still getting the same error).
    In your case I would try to keep just the most important classes - IReport, frmReminder, NewReports, NewReminder (with only the most necessary code).

    It will take some time, but it is likely to uncover your problem. In the case that you have discovered a bug in CLR, then you will have a small repro which you can post here and it can be easily used for a bug report.
    Without providing a small (10-100 lines) repro it is unlikely that anyone will be able to help you ...

    -Karel
    Thursday, June 25, 2009 8:37 PM
    Moderator
  • I basically have it tracked down to when I load the dll into an Assembly object and try to run Assembly.GetTypes() I am getting the error.  Does this help at all?
    Patrick Mallahan
    Thursday, June 25, 2009 10:07 PM
  • It doesn't help. It just says that loading one of your type in your assembly fails, because CLR thinks it is not fully implemented (missing interface method implementation) ... and we already knew that
    As I said earlier, without a small repro it is hard to help you ... Try to delete as many types from your code as possible, experiment with it ...

    Write a small app which will call just Assembly.GetType("NewReminder") on your application ... does it still fail?
    If yes, delete some types from your assembly and check that it still fails. Keep as few types in as possible ... that's the way how to get a small repro ...

    Friday, June 26, 2009 1:08 AM
    Moderator
  • It doesn't help. It just says that loading one of your type in your assembly fails, because CLR thinks it is not fully implemented (missing interface method implementation) ... and we already knew that
    As I said earlier, without a small repro it is hard to help you ... Try to delete as many types from your code as possible, experiment with it ...

    Write a small app which will call just Assembly.GetType("NewReminder") on your application ... does it still fail?
    If yes, delete some types from your assembly and check that it still fails. Keep as few types in as possible ... that's the way how to get a small repro ...

    Ok, I finally got the code to a point where it will try to load it.  Here is an example of how I am trying to load it now:

    DirectoryInfo dirPlugins = new DirectoryInfo(installLocation);
    
                if (dirPlugins.Exists)
                {
                    foreach (FileInfo pluginFile in dirPlugins.GetFiles("*.dll"))
                    {
                        try
                        {
                            // Load the assembly whose name was passed on the command-line
                            Assembly assem = Assembly.Load(Path.GetFileNameWithoutExtension(pluginFile.FullName));
    
                            // Pass the assembly object to a constructed LateBinderForm
                            LateBinderForm binder = new LateBinderForm(assem, this);
                            //Old way of trying to load that was causing an error:
                            //Application.Run(new LateBinderForm(assem, this));
                        }
                        catch (ReflectionTypeLoadException loadExcep)
                        {
                            docMinderServer.Log(loadExcep.LoaderExceptions[0].Message + " -- While Loading Plugins");
                        }
                        catch (Exception ex)
                        {
                            docMinderServer.Log(ex.Message + " -- While Loading Plugins");
                        }
                    }

    That is where I try to load. Now here is my LateBinderForm code:

    class LateBinderForm : Form
        {
            public LateBinderForm(Assembly a, frmReminder parent)
            {
                // Make it MDI
                IsMdiContainer = true;
    
                // Get the types in the assembly
                Type[] types = a.GetTypes();
                // Iterate and find types derived from Form Instantiate them
                foreach (Type t in types)
                {
                    if (t.BaseType == typeof(IReports))
                    {
                        IReports plugin = (IReports)Activator.CreateInstance(typeof(IReports));
                        //plugin. = this; // Set as MDI children
                        plugin.Initialize();
                    }
                }
            }
        }

    Here is my IReports:

    public interface IReports
        {
            void Initialize();
        }

    And finally here is my plugin code:

    class ReminderReports : IReports
        {
            public void Initialize()
            {
                MessageBox.Show("I am loaded!");
            }
        }



    I cannot get the message box to show but I don't get the error any longer. Also, if you look in the first code block, you can see where i iterate through the types and check for IReports.  IReports is not showing up at all.

    Patrick Mallahan
    Monday, June 29, 2009 7:22 PM
  • Interface can never be BaseType - see MSDN docs on BaseType! It will give you advice to call GetInterfaces instead.

    Instead of line (in LateBindForm constructor):
        if (t.BaseType == typeof(IReports))
    use corect condition:
        if (typeof(IReports) in t.GetInterfaces())

    -Karel
    Wednesday, July 8, 2009 1:43 AM
    Moderator
  • Interface can never be BaseType - see MSDN docs on BaseType! It will give you advice to call GetInterfaces instead.

    Instead of line (in LateBindForm constructor):
        if (t.BaseType == typeof(IReports))
    use corect condition:
        if (typeof(IReports) in t.GetInterfaces())

    -Karel

    Thanks so much.  I kinda feel dumb now, but I guess you live and learn.
    Patrick Mallahan
    Monday, July 13, 2009 4:44 PM