MilleB
MilleB

Reputation: 1580

Exception not caught when loading an assembly and calling a function with reflection

So I have a test that load an assembly, get a specific class and run a function. It works fine except that if I get an exception inside the class I can't catch it.

In the test I start with to create a new Appdomain like this:

    [STAThread]
    [Test, TestCaseSource("FromFile")]
    public void AutomationTest(string testCasePath)
    {
        var pathToDll = Assembly.GetExecutingAssembly().Location;
        string assemblyPath = ...
        AppDomainSetup domainSetup = new AppDomainSetup
        {
            PrivateBinPath = pathToDll
        };
        AppDomain domain = AppDomain.CreateDomain("TempDomain", null, domainSetup);
        InstanceProxy proxy = domain.CreateInstanceFromAndUnwrap(pathToDll, typeof(InstanceProxy).FullName) as InstanceProxy;
        if (proxy != null)
        {
            proxy.LoadLibrary(assemblyPath);
        }
        AppDomain.Unload(domain);
    }

Then I call on my class like this:

    internal class InstanceProxy : MarshalByRefObject
    {
        public void LoadLibrary(string path)
        {
            Assembly asm = Assembly.LoadFrom(path);
            Type[] types = asm.GetExportedTypes();
            Type type = types.FirstOrDefault(t => (t.FullName == "MyNamespace.SomeClass"));
            if (type != null)
            {
                var obj = Activator.CreateInstance(type); 
                try
                {
                    obj.GetType().InvokeMember("Run",
                        BindingFlags.InvokeMethod,
                        Type.DefaultBinder, obj, null);
                }
                catch (Exception e)
                {
                    Assert.Fail(e.Message);
                }
            }
        }
    }

So when I get an exception the code will stop to run at my InvokeMember even when I have a try/catch. Is there some way to get around this?

Update 1:

I Tried to change LoadLibrary to this as João Mendes said:

        public void LoadLibrary(string path)
        {
            Assembly asm = Assembly.LoadFrom(path);
            Type[] types = asm.GetExportedTypes();
            Type type = types.FirstOrDefault(t => (t.FullName == "MyNamespace.SomeClass"));
            if (type != null)
            {
                var obj = Activator.CreateInstance(type);
                var method = type.GetMethod("Run");
                try
                {
                    method.Invoke(obj, null);
                }
                catch (Exception e)
                {
                    Assert.Fail(e.Message);
                }
            }
        }

But still breaks inside the try.

Upvotes: 0

Views: 227

Answers (2)

MilleB
MilleB

Reputation: 1580

So after some looking (and comment from Ron Beyer I found the solution).

First I simply went to Debug > Window > Exception settings and and unchecked all Break when thrown. This didn't solve the kind of exception I had thought.

Then when I run the software again and saw that the exception window had it's own checkbox (something similiar to "break when thrown"), so I unchecked it and now it run perfectly without me seeing the exception.

Upvotes: 0

João Mendes
João Mendes

Reputation: 1425

Yes. Instead of InvokeMember, use GetMethod("Run") to get a reference to a MethodInfo object, then use that to call Invoke(obj, null).

That way, you don't have to mess with binders and binding flags, and you also get a nice TargetInvocationException you can catch.

Upvotes: 1

Related Questions