1

Basically the problem is that I'd like to invoke a method in an unreferenced assembly, but can't seem to find the right call for instantiating the class. I've tried things like a simple Type t = Type.GetType("MyApp.Helper") which returns null, and Assembly.LoadFrom("MyApp.Helper") which throws a security exception.

In the example below, two projects/assemblies (Helper.dll and Menu.dll) are compiled separately into a common 'libs' folder, but do not reference each other. Main.dll references both, and the references are set to 'Copy local' in VS. So when the app runs, the Main.xap should contain all three assemblies and they should be loaded into the same application domain. Or so goes my understanding. Is this an impossible quest? I see lots of comments regarding plug-ins but so far I haven't seen examples for this specific design. For example, I suppose I could do something like Jeff Prosise describes here, but I'd rather have everything in one package.

Here's a sketch of my code:

In one project/assembly, I have a worker class:

namespace MyApp.Helper {  
    public class Helper {  
        public void ShowHelp() {  
            Console.Write("Help!");  
        }  
    }  
}  

In another project/assembly, I have a menu class which tries to invoke the helper:

namespace MyApp.Menu {
    public class Selector {
        public void InvokeSelection(string className, string functionName) {

            // fails: t will be null
            Type t = Type.GetType(className);  

            // fails: t will be null
            t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Helper", "Helper"));

            // however, this works (reference to main assembly?)
            t = Type.GetType(string.Format("{0}.{1}, {0}, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null", "MyApp.Main", "Worker"));

            // and, I'd like to do something like the following
            // t.InvokeMember(functionName, ...);
        }
    }
}

Finally, I have the main app assembly:

namespace MyApp.Main {
    public class Main {
        public static void Main() {
            MyApp.Menu.Selector sel = new Menu.Selector();
            sel.InvokeSelection("MyApp.Help.Helper", "ShowHelp");  // fails
            sel.InvokeSelection("MyApp.Main.Main", "Worker"); // works in some cases
        }
        public void Worker() {
            Console.Write("Work!");
        }
    }
}

Thanks for any ideas!

-Chris.

Chris
  • 13
  • 3

2 Answers2

1

You need to get the Assembly object, then call its GetType method.

However, I don't see why you're using Reflection at all.
You can call the method normally from your main project.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • SLaks,thanks to you and JeffN825. I had tried Assembly.Load but it didn't work. My simple example was too simple. I have a good many custom assemblies and it seems I didn't reference the one I was testing against. I did try 'Assembly.Load' + 'GetType()' but after trying so many different techniques, I didn't get all the parts aligned. Many thanks for cutting the haze! To answer your question, I'm initializing the menu from a config file which goes straight to the menu lib, so the main app never sees it. The error is from refactoring a monolithic app that originally worked. Cheers! – Chris Nov 29 '10 at 19:20
0

First, you should note that since it's SL, you can't invoke private/protected/internal members.

Second, try this:

    public void InvokeSelection(string className, string functionName) {

        var asm = Assembly.Load("MyApp.Helper, Version=1.0.0.0, Culture=\"\", PublicTokenKey=null"); // double check this is correct!

        Type t = asm .GetType(className);  

        // and, I'd like to do something like the following
        // t.InvokeMember(functionName, ...);
    }
Jeff
  • 35,755
  • 15
  • 108
  • 220