0

I am trying to replicate a functionality with reflection but end up getting

CreateFormatMethod.Invoke(typDbFormatClass, null)' threw an exception of type 'System.Reflection.TargetInvocationException' object {System.Reflection.TargetInvocationException}

Inner Exception Shows Object reference not set to an instance of an object. System.NullReferenceException

InnerException null

Stacktrace

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]   arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at AB.INIT.stringToValue(String valueInUnits, String dimension, String sourceUnit, String destinationUnit)

I am trying to access a static method of abstract class here. Below is the direct reference code that works perfectly .

Binit.Core.Database.DbFormat format;
format = Binit.Core.Database.DbFormat.Create();
format.Dimension = 
   DbDoubleDimension.GetDimension((DbDimension)Enum.Parse(typeof(DbDimension), dimension));

Reflection Code which fails and shows targetinvocationexception

Assembly CoreDatabaseAssembly = Assembly.LoadFrom(Path.Combine(APath, @"Binit.Core.Database.dll"));
Type typDbFormatClass = CoreDatabaseAssembly.GetType("Binit.Core.Database.DbFormat");

MethodInfo createFormatMethod = typDbFormatClass.GetMethod("Create", BindingFlags.Static | BindingFlags.Public, null, new Type[] { }, null);
object objDbFormat = createFormatMethod.Invoke(typDbFormatClass, null);

Type typDbDimension = CoreDatabaseAssembly.GetType("Binit.Core.Database.DbDimension");

Type typDoubleDimensClass = CoreDatabaseAssembly.GetType("Binit.Core.Database.DbDoubleDimension");
MethodInfo DbDoubleDimensionMethod = typDoubleDimensClass.GetMethod("GetDimension", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typDbDimension } , null);
object[] parametersDbDoubleDimen = new object[] { Enum.Parse(typDbDimension, dimension) };
object objDimension = DbDoubleDimensionMethod.Invoke(typDoubleDimensClass, parametersDbDoubleDimen);

i am not sure how to do the casting for below Enumerator with reflection and i doubt if this could be causing the issue

(DbDimension)Enum.Parse(typeof(DbDimension), dimension)

object[] parametersDbDoubleDimen = new object[] { Enum.Parse(typDbDimension, dimension) };

The dbFormat Class is as below.

namespace Binit.Core.Database
{

public abstract class DbFormat
{
    protected static DbFormat m_internalDbFormat;

    protected DbFormat();

    public static DbFormat Create();

    public static DbFormat Create(DbFormat other);

}
}
battech
  • 803
  • 2
  • 13
  • 25
  • Can you post the full exception including stack trace and inner exception? – Blorgbeard Aug 19 '15 at 05:03
  • Looks like it should be `object objDbFormat = createFormatMethod.Invoke(null, null);` since it's a static method with no parameters. – Blorgbeard Aug 19 '15 at 05:04
  • `TargetInvocationException` indicates that the null reference exception was thrown from within `Create`. Is there some initialization that you aren't doing? – Blorgbeard Aug 19 '15 at 05:07
  • i am wondering if there is a seperate initialization i must be doing because all that i do with direct reference is to call Binit.Core.Database.DbFormat.Create() and this is tried to be replicated with reflection. – battech Aug 19 '15 at 05:35
  • Does `DbFormat.Create` uses the `app.config` to decide what format to create? – Taher Rahgooy Aug 19 '15 at 06:24
  • i couldn't find an app.config file for the project having DbFormat class. So the answer is no i guess – battech Aug 19 '15 at 06:35
  • I've created a simple example from your code, and it works properly. I guess there is a problem in the `Create` function logic, how it make the decision to return what `DbFormat`, maybe it needs other resources that not loaded – Taher Rahgooy Aug 19 '15 at 06:38
  • Yes. i was able to get pdbs for the Dbformat dll and found that create method is doing return m_internalDbFormat; and this is throwing null exception. Now my confusion is why it is not set with proper values while using reflection. Because i am infact using only create method when working with direct reference as well. So basically with direct reference the dependency dlls might be loading and it would be setting this property. But how do i be doing the same with reflection – battech Aug 19 '15 at 08:37

1 Answers1

1

If I am understanding what you have here correctly, Binit.Core.Database.DbFormat is a nested class with a static method Create

If that is true then it is incorrect to do this:

createFormatMethod.Invoke(typDbFormatClass, null);

Because as a static method the first parameter of Invoke should be null

However, I am not sure why that would be causing a null exception though, because usually when I see something like this, it is my function throwing the exception (however it looks like you're running it fine so I am not sure...)

Community
  • 1
  • 1
HaroldHues
  • 308
  • 1
  • 6
  • This is correct, but the null reference is because `createFormatMethod` - that is, it was unable to find the method 'Create' – Rob Aug 19 '15 at 05:20
  • i tried changing it to object objDbFormat = createFormatMethod.Invoke(null, null); however the error is same – battech Aug 19 '15 at 05:29