Accessing Compiled Properties & Fields

Documentation wrote using version 1.2

Accessing a scripts Properties or Fields are pretty easy using rScript. The first thing that needs to happen in order for your application to access them at run-time is the instancing of the ScriptFactory Type. It will instance and provide you with a reference to a script automatically. You must have a reference to an Assembly that has already been loaded or created. If the compilation of your script was successful, then you will already have a loaded Assembly.
The ScriptFactory does not return an Object that references your script, but rather provides you with a ScriptObject that contains some helper methods for accessing properties. It even contains the actual reference to the script.

Before we begin, I want to make sure you understand the difference between Properties and Fields. A Property is as such.

    public string PlayerName {get;set;}


and a Field is as such.

    public string PlayerName = "Bobby";


It is recommended that you use Properties for standardization, however Fields are supported as well. Our example script provided in the Using rScript to Compile Scripts documentation, we will learn how to access both Properties and Fields dynamically.

Note It is critical that you use the correct GetField() or GetProperty() method when trying to access either a Field or Property. If you are trying to find a Field titled playerName and have built it as a Property in your script, then you will not have access to it.

Script.cs
using System;

namespace RuntimeExample.Scripts
{
    public class Wheel
    {
        public Int32 Size = 20;

        public Double Width
        {
            get
            {
                return 8.5;
            }
        }

        public void GetTireBrand()
        {
            System.Windows.Forms.MessageBox.Show("Super Tire Co.");
        }
    }
}


Program.cs
using System;

namespace RuntimeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            rScriptingEngine.CompileEngine _CompileEngine = new rScripting.CompileEngine();
            System.IO.FileInfo file = new System.IO.FileInfo(@"C:\Scripts\Script.cs");

            //Since our script contains a call to MessageBox, we must add a reference to the Windows Forms assembly.
            //Note that even though we don't use the messagebox in this lesson, we still need to reference the assembly because the script contains it.
            _CompileEngine.AddAssemblyReference("System.Windows.Forms.dll");

            //Compile our script file.
            Boolean isCompiled = _CompileEngine.Compile(file);

            if (isCompiled)
            {
                 //Create a Script Factory. This contains a collection of all scripts compiled, if multiple are compiled.
                rScripting.ScriptFactory factory = new rScripting.ScriptFactory(_CompileEngine.CompiledAssembly);

                //Get a reference to our compiled script.
                rScripting.ScriptObject script = factory.GetScript("Wheel");

                //Write out the size of the Wheel, by accessing it's properties.
                Console.WriteLine("The size of the wheel is: " + script.GetField("Size"));
                Console.WriteLine("The width of the wheel is: " + script.GetProperty("Width"));
            }
        }
    }
}


As you can see, the ScriptFactory returned a ScriptObject Type that allowed you to access the objects field.. You also have access to the object itself, via the ScriptObject.Instance Property.
You can also perform a Type Cast for non-string Fields or Properties.

  //One way of accessing the value.
  someStringField = obj.GetField("someFieldValue").ToString();

  //Another way is Type Casting.
  someStringProperty = (string)obj.GetProperty("someFieldValue");

  //Type Casting can be used for other value types as well.
  Size = (int)obj.GetField("Size");


While the previous examples are the preferred and safe way to access Fields & Properties, you can do it in another way as well. Thanks to .NET 4.0's new dynamic Type, you can reference the Instance via the dynamic Type and then access it's Properties and Fields provided you know their before hand. If you attempt to access them like this and they do not exist, then an exception will be generated.

            Boolean isCompiled = _CompileEngine.Compile();
            if (isCompiled)
            {
                rScripting.ScriptFactory f = new rScripting.ScriptFactory(_CompileEngine.CompiledAssembly);
                rScripting.ScriptObject obj = f.GetScript("Wheel");

                dynamic testScript = obj.Instance;
                double width = testScript.Width;
            }


or...
            Boolean isCompiled = _CompileEngine.Compile();
            if (isCompiled)
            {
                rScripting.ScriptFactory f = new rScripting.ScriptFactory(_CompileEngine.CompiledAssembly);
                rScripting.ScriptObject obj = f.GetScript("Wheel");

                int size = obj.GetField().Size;
            }


You can also load none scripted assemblies into the ScriptFactory and access their Properties and Fields as well.

            System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(@"C:\SomeAssembly.dll");
   
            rScripting.ScriptFactory f = new rScripting.ScriptFactory(assembly);
            rScripting.ScriptObject obj = f.GetScript("SomeType");

            int index = (int)obj.GetField("SomeIndex");

Last edited Dec 12, 2010 at 1:36 PM by Scionwest, version 14

Comments

No comments yet.