[3DS Max][C#] Iterating on a DLL using Visual Studio ('unload' Assemblies in Max?)

What’s the best approach for iterative C# DLL development with Visual Studio and 3DS Max?

I’m using MS Visual C# Express to write C# class libraries
these .DLLs are load in Max Script using dotNet.LoadAssembly

But iteration is a b*tch because I can’t “unload” an assembly : I have to restart max.

there has to be more efficient way to test my hand built C# Dot Net objects in MaxScript…

[edit] solution found

[UPDATED] added commands to instantiate a class as an object , or call a function in a static class, optionally passing parameters as mxs arrays in either case.
[UPDATED] links fixed.

The dllManager.ms script is posted on my own code page for easier maintenance.

Check this post by Susanta: http://forums.cgsociety.org/showpost.php?p=5635627&postcount=12

thank you for the response.
I found that thread yesterday and began adapting it to a simple DLL managing MXS tool with a reload button.
need to test it more, will post results if it works.

a more concise approach was posted in my cg talk thread
At fist blush it seems to work, and skips the need for explicit Assembly versions. I will test more at lunch.

I tested and rolled it into a simple MXS tool for easy DLL reloading in Max:

[UPDATED] added ability to instantiate a Class with parmaters.
I moved my dllManager.ms script to my own code page for easier maintenance.

Very cool, thanks for sharing!

I hope you find it useful. Right now instantiate className only handles simple Classes with no constructor arguments.

other features I’ve been challenged to add are :

  1. Create instance with parameters.
  2. Invoke a method or property on a static class.

1.) is Harder than I thought, if I must avoid the use of dotNetObject when initiating.
My C# test class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyNameSpace
{
    public class MyClassWithArg
    {
        public string arg;
        public MyClassWithArg(string thisArg)
        {
            arg = thisArg;
        }
        public string sayArg()
        {
            return ("MyClassWithArg.sayArg has been called.
	MyClassWithArg.arg = " + arg + ".
");
        }
    }
}

It’s easy enough to call with an argument using this MXS

MyClassWithArgs=dotNetObject "MyNameSpace.MyClassWithArg" "hello, world" 

but this gives an error


MyClassWithArgs=dllManager.assembly.CreateInstance "MyNameSpace.MyClassWithArg"  "hello,world"
-- Runtime error: No method found which matched argument list

as does converting the argument into a System.Object[] dotnet value:


dotNetArg=dotNet.ValueToDotNetObject #("hello,world") (dotNetObject "System.Object")
MyClassWithArgs=dllManager.assembly.CreateInstance "MyNameSpace.MyClassWithArg"  dotNetArg
-- Runtime error: No method found which matched argument list

It seems to be an issue in properly passing the arguments to the constructor.
Anyone have insight?

Stack Overflow to the rescue.

Looks like System.Assembly.CreateInstance cannot actually create an instance AND pass and argument to the constructor,
but System.Activator.CreateInstance can do it. The argument(s) still need to be converted into dotNet objects before passign from MXS.

Msx code

activator = dotNetClass "System.Activator"
dotNetType=dllManager.assembly.GetType("MyNameSpace.MyClassWithArg")
dotNetArg=dotNet.ValueToDotNetObject #("hello,world") (dotNetObject "System.Object")
MyClassWithArgs=activator.CreateInstance dotNetType dotNetArg
--dotNetObject:MyNameSpace.MyClassWithArg
MyClassWithArgs.arg
--"hello,world"

I’ll roll this into the code above
Though, I admit to being fairly over my head with C#, I do not know if there is any risk to creating all these DotNetClass objects just for one method use.
[EDIT] code in post#5 updated