Author Topic: How to use a method in another Assembly?  (Read 529 times)

0 Members and 1 Guest are viewing this topic.

Jeff_M

  • King Gator
  • Posts: 3980
  • C3D user & customizer
How to use a method in another Assembly?
« on: April 09, 2020, 12:52:32 PM »
I have 2 projects. In the first I am checking to see if Civil 3D is the currently running application. If it is, I load the second Assembly and use a Method in it which returns a single integer. If I include the second project in the References of the first it works fine since the namespace and class can be seen. However, when it is referenced and built, the C3D assemblies get copied into the build folder even though they are set to not copy Local. This prevents the tool from running outside of Civil 3D (such as plain Autocad). So what I need to do is be able to call that method with Reflection, but I'm having a difficult time getting the right format.
Code - C#: [Select]
  1.                     var assy = LoadExtension(Name); //This works, assembly is loaded
  2.                     unitType = (int)assy.GetType().InvokeMember("GetC3DScalesInt", BindingFlags.InvokeMethod,null, assy, null); //This fails, as does the following with the namespace and class included
  3.                     unitType = (int)assy.GetType().InvokeMember("C3DPortion.GetC3DScales.GetC3DScalesInt", BindingFlags.InvokeMethod,null, assy, null);
  4.  
Can this even be done? Am I barking up the wrong tree?

Thanks!

huiz

  • Swamp Rat
  • Posts: 874
  • Certified Prof C3D
Re: How to use a method in another Assembly?
« Reply #1 on: April 09, 2020, 01:22:12 PM »
Yes, no problem. I do this with a second project to attach Object Data and Property Sets, which can't be done in plain AutoCAD.
Later I will add my code, I am on my mobile phone now.
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

huiz

  • Swamp Rat
  • Posts: 874
  • Certified Prof C3D
Re: How to use a method in another Assembly?
« Reply #2 on: April 09, 2020, 01:40:45 PM »
Ok, why not adding the code right now :-)




I have two projects. Project 1 is the main dll, Project 2 is a dll with just code that works in Civil 3D or Map 3D.


Project 1: Do not reference Project 2. Only create a new command or a right mouse button menu item or so. There you check if you are running inside Civil 3D and if not, you can show a nice message.


If you are running inside Civil 3D you can load the seperate dll and call the function you need:






Code: [Select]



#if DEBUG
                    string dllFile = FileSystem.Functions.GetMyPath() + @"..\..\..\Project 2\bin\Debug\Project2.dll";
#else
                    string dllFile = FileSystem.Functions.GetMyPath() + "Project2.dll";
#endif


                    if (FileSystem.Functions.FileExist(dllFile) == false)
                    {
                        return ExportResult.ModuleNotFound;
                    }


                    // Load the dll
                    Assembly assembly = Assembly.LoadFrom(dllFile);
                    System.Type assemblyClass = assembly.GetType("Project2");


                    if (assemblyClass == null)
                    {
                        return ExportResult.ModuleNotFound;
                    }


                    // var methodInfo = t.GetMethod("MyFunction", new Type[] { typeof(int), typeof(string) });
                    MethodInfo methodInfo = assemblyClass.GetMethod("MyFunction"); // I don't use parameters here


                    if (methodInfo == null)
                    {
                        return ExportResult.FunctionNotFound;
                    }


                    // object[] constructorParameters = new object[0];
                    // constructorParameters[0] = 999; // First parameter.
                    // constructorParameters[1] = 2;   // Second parameter.


                    // Create Instance of the Class (Constructor)
                    object instance = System.Activator.CreateInstance(assemblyClass, null); // No parameters needed for the constructor so I use null


                    // Function parameters
                    object[] parameters = new object[2];
                    parameters[0] = objectIds;
                    parameters[1] = dataTable;


                    // Run Method with optional parameters (I feed it with objectids and a datatable) en get result back (in this case I return a bool)
                    bool success = System.Convert.ToBoolean(methodInfo.Invoke(instance, parameters));


                    if (success == true)
                    {
                        return ExportResult.Correct;
                    }




Works quite good.

The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.

Jeff_M

  • King Gator
  • Posts: 3980
  • C3D user & customizer
Re: How to use a method in another Assembly?
« Reply #3 on: April 09, 2020, 02:03:50 PM »
Thank you, huiz! What does the beginning of your 2nd dll class look like? I'm getting null for the assemblyClass...I used the assembly name, and the class name, both return null so I must be missing something in that class. Scratch that, I figured out I had to use the Namespace and the class:
 
Code - C#: [Select]
  1. Type assemblyClass = assembly.GetType("C3DPortion.GetC3DScales");

Now working perfectly, thanks again!
« Last Edit: April 09, 2020, 02:41:16 PM by Jeff_M »

huiz

  • Swamp Rat
  • Posts: 874
  • Certified Prof C3D
Re: How to use a method in another Assembly?
« Reply #4 on: April 09, 2020, 02:55:01 PM »
I'm glad I could help :-)
The conclusion is justified that the initialization of the development of critical subsystem optimizes the probability of success to the development of the technical behavior over a given period.