# Unity [.net] .NET Scripting - Sharing Types/Objects

This topic is 5043 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Let me try and get this into some understandable terms as my research is confusing me - it doesn't help being a relative newcomer in the .NET world either [grin] I've been trying to implement some scripting in a VB.NET application using the inbuilt .NET compiler. I've followed the stuff in this thread and on CodeProject and got a mini script compiler up and running ok. The problem I'm having now is that I want to expose some (not all) functionality from my host application to the scripting environment. Mainly, I have several custom data field objects that I'd like the scripts to be able to read. So my question is, how do I allow my scripting environment access to certain types from the host assembly and expose some objects to the script? It has something to do with Reflection, which is obvious. However, all my searching on the subject is coming up blank. Does anyone have any examples of what I'm trying to achieve? Thanks

##### Share on other sites
Off the top of my head, have a separate assembly that contains all of the types you want the script to have access to and compile the script with a reference to that assembly. I haven't done much in the way of runtime compilation with .NET so I'm not sure if there would be any security risks associated with that (assuming that the types in your assembly are all considered 'safe').

##### Share on other sites
Ok, I've worked out how to get an assembly to reference another and the associated types, data et cetera. However, the problem is that the script has access to all of the types from the host, something that isn't a huge problem, but I'd rather not have it there. So the solution looks to me now as if I need to do as joanus suggested and have a 'proxy' assembly inbetween the host and the script assembly. I'll look into doing this for now, but would be grateful of any further insights you nice people can offer.

Thanks

EDIT:

A couple of useful resources I've found in searching this:

LiveCode.NET

[Edited by - evolutional on September 21, 2004 5:27:19 AM]

##### Share on other sites
Forgive me if this is a waste of your time.

The approach that was taken was to define a set of interfaces that specified the definition of: a) the framework that loaded the assemblied and b) the assemblies themselves.

Being a business environment, and given that the client wants something that works yesterday, what we did was make the framework implement an interface, and passed a reference of the framework to the plugin. The interface defined functions that gave the plugin access to properties of the framework.

Since this is a game development site, this may be totally inappropriate for your problem, but for us it worked a treat.

Let me know if you want further details.

##### Share on other sites
I'd love further details if you're willing to supply them, as I'm essentially learning scripting/plugins and how they work in .NET. The context of a particular problem domain doesn't really apply in this instance, so I'd like to see what you came up with.

I've also been reading Writing Plugin-based .NET applications which is useful. As I say, I'm a .NET n00b but looking to explore it a lot more in the future.

##### Share on other sites
Okay.

Our particular application is designed to be a framework from which we can load additional modules that are written post-deployment, and don't require us to constantly have to re-compile the framework application.

Interface-wise, the framework is a shell that loads tab pages (our plugins are written as user controls and are tab pages), and each tab page will process different input files.

Additionally, each assembly, while containing logic to load and process data files, also needed to manage a collection of settings.

In order to do this, we have three interfaces defined:

namespace TheApp{public interface Plugin{	System.Windows.Forms.TabPage TabPage	{		get;	}	bool Init(TheApp.Framework f, string tabText, string configDir, string pluginName);	}public interface Framework{	System.Data.SqlClient.SqlConnection SqlCnn	{		get;	}	Control.MessageBar MessageBar	{		get;	}}public interface OptionInterface{	bool Init(TheApp.Framework f, string configDir);}}

So these interfaces define the functionality of the framework, the plugin and the settings component of each interface.

The idea was to define an interface for the framework so that, if you look at the Init() function of the Plugin interface, we pass the framework in as a parameter, and then the Framework interface defines how and what we get access to (in our case, the SqlConnection and a MessageBar).

In order to load the plugin into the framework, all we do is (from the framework):
using System.Reflection;using System.Runtime.Remoting;using System.EnterpriseServices;/*     .... */ObjectHandle h;h = Activator.CreateInstanceFrom(p.m_filename, p.m_namespace + "." + p.m_class);TheApp.Plugin i = (TheApp.Plugin)h.Unwrap();i.Init(this, p.m_title, m_configPath, p.m_class);tcMain.TabPages.Add(i.TabPage);

Other things that we do that aren't shown here including checking each loaded assembly to ensure that it uses the correct interface, retrieve information about the assembly, etc.

Since I'm coding this as a contractor, I need to be careful with what I post. If you would like to discuss this stuff further, feel free to send me an email.

Cheers,
Brendan.

##### Share on other sites
Evo, I haven't done much work using a .NET language as a scripting language, but perhaps it helps if you think about the problem in the reverse way. Perhaps the issue isn't that your scripts need to already be aware of your game entities. Perhaps, your game entities need to make themselves aware TO the scripts. So, once you create the object out of the script, then you call a Register() function on the object from the script that accepts a Game object as a parameter. And then anytime the script needs to call any functionality in the game, it calls a method or member of the Game object it was Register'd with. So, in pseudo-code, it might look like this

// Game myGame = new Game();// GameObject zombie = new GameObjectFactory.CreateZombie();Script myScript = ScriptManager.LoadFromFile("myScript.gsc");myScript.Register(myGame, zombie);....myScript.Execute()

And then in the script itself you would have something like:

class MyScript : Script{    private Game game = null;    private GameObject gameObject = null;    public MyScript()    {        // non-game specific load here    }    public void Register(Game game, GameObject gameObject)    {        this.game = game;        this.gameObject = gameObject;        // various other game-specific load here    }    public void Execute()    {        // use Game object to get data from or execute methods                // stuff like this        // Position myPosition = gameObject.Position;        // int score = this.game.Score;        // gameObject.Move(someX, someY);    }}

This is just a thought though. It might work when approaching it from this different angle. If not, hopefully it might give you a different idea how to solve your problem. I hope this helps in some way! Good luck!

##### Share on other sites

Think of the new app domain as a black box that you can put the script objects in. For security reasons, the scripts themselves can't get out of the box and if they do break anything, it only breaks the box, not your application.

Just a thought though. Any time you are "loading" objects at runtime, it is a very good habit to get into loading them into a seperate app domain. Your application will be happy, and all the users of your application will be happy :).

##### Share on other sites
Thanks for your comments guys. I'm torn as to which apprach to adopt now, the script or the plugin method. The plugin method does actually seem a lot cleaner than the scripting, mainly because being a .NET n00b the whole application is a greater challenge than it would normally be as I'm learning the .NET framework as I'm going on.

Thanks for the idea Blowfish, however the problem seems to be registering my application types with the script interface. I've never done anything like this in .NET so it's all new territory. I'll keep playing, perhaps go with the plugin solution and take up the scripting idea later on when I feel more accustomed to .NET.

Oh and Blowfish - kudos for using a Zombie in your example [grin]

##### Share on other sites
This is how you can do it in C# so maybe it gives some glue how to do it in VB.

First create class libary (dll) wich containts all the functions and classes/types you want to expose for scripting.

Then
CompilerParameters	pars = new CompilerParameters();pars.ReferencedAssemblies.Add( "ClassLibTest.dll" );

I hope it helps any.

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
18
5. 5

• 14
• 18
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631760
• Total Posts
3002174
×