Welcome to MSDN Blogs Sign in | Join | Help

DLR Hosting API : How to create ScriptScopes using backing symbol dictionaries to implement dynamic variable lookup

The factory methods used to create a ScriptScope object have overloads that take a 'IAttributeCollection' object to create the scope using the collection as a backing store. This feature is very useful and any app that needs non trivial Hosting would mostly use this feature.

The easiest way to implement the IAttributeCollection interface is to implement the CustomSymbolDictionary defined in the the Hosting API. Once this is done, all variable access by a script executing in the context of this scope will result in a call to the set or get methods that were overriden.

You can do some interesting things like chaining of scopes, inspecting variable values upon script access, value validation etc using this symbol dictionary implementation.

The following example uses a custom symbol dictionary to chain scopes to create a pseudo hierarchy.

using System;

using Microsoft.Scripting;

using Microsoft.Scripting.Hosting;

using Microsoft.Scripting.Runtime;

 

namespace ScopeOps {

    public class ScopeHiererchy {

        public static void Main() {

            ScriptEngine eng = new ScriptRuntime().GetEngine("py");

            ScriptScope baseScope = eng.CreateScope();

 

            var dict = new DynamicLookupDictionary(baseScope);

 

            //set variables in the base scope.

            baseScope.SetVariable("base_int", 100);

            baseScope.SetVariable("base_string", "from base");

 

            ScriptScope useScope = eng.CreateScope(dict);

            var src = eng.CreateScriptSourceFromString(

                "print base_int\nprint base_string",

                SourceCodeKind.Statements);

 

            //'useScope' doesn't have the variables accessed by the script yet.

            //The overriden 'get' method dynamically looks up the variable in the base scope.

            src.Execute(useScope);

        }

    }

 

    internal class DynamicLookupDictionary : CustomSymbolDictionary {

        private ScriptScope _baseScope;

 

        public DynamicLookupDictionary(ScriptScope baseScope):base() {

            _baseScope = baseScope;

        }

 

        //This method would be invoked whenever a script executing in the context of this scope

        //accesses a variable

        protected override bool TryGetExtraValue(SymbolId key, out object value) {

            //If the variable is part of the base scope, return that value - this effectively

            //creates a 'scope chain'

            if (_baseScope.TryGetVariable(SymbolTable.IdToString(key), out value)) {

                return true;

            }

 

            value = null;

            return false;

        }

 

        public override SymbolId[] GetExtraKeys() {

            return null;

        }

 

        protected override bool TrySetExtraValue(SymbolId key, object value) {

            return false;

        }

    }

}

Published Friday, August 15, 2008 8:04 PM by seshadripv

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# funny wallpaper » DLR Hosting API : How to create ScriptScopes using backing symbol dictionaries to implement dynamic variable lookup

# re: DLR Hosting API : How to create ScriptScopes using backing symbol dictionaries to implement dynamic variable lookup

Seshadri,

Can you explain a bit about TrySetExtraValue method? For example, I want to control the execution of the line "myObject = 10" within the script where myObject is a custom symbol.

Appreciate your help

Thanks

Sree

Thursday, February 05, 2009 10:29 AM by Sree

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker