Using CLR Objects without qualifing full namespace (extension)

May 2, 2010 at 1:25 PM

it would be nice if JintEngine provides a function to set the "Global" namespace like this:

JintEngine engine = new JintEngine();
engine.GlobalClrNamespace = "Myproject.Javascript.Dom";

Any class within this namespace should by used without fully qualified namespace.

a = new Myproject.Javascript.Dom.Document();

becomes

a = new Document();

(The first version will be possible too)

for classes under this namespace it should be possible to provide a own permission set which is per default new PermissionSet(PermissionState.Unrestricted);

This makes it possible to integrate something like DOM or whatever i need on predefined classes without any friction.
I try to implement it myself, but i've found your lib hours ago so that may be difficult. My starting point is the CachedTypeResolver class.

Regards Thomas 

 

May 2, 2010 at 3:13 PM

Extending the CachedTypeResolver is straight forward and works very well. Here are my code changes :

JintEngine.cs:

        public string GlobalClrNamespace
        {
            get { return visitor.GlobalClrNamespace; }
            set { visitor.GlobalClrNamespace = value; }
        }
ExecutionVisitor.cs:

...
public
string GlobalClrNamespace { get; set; } ...
this
.typeResolver = new CachedTypeResolver(this);
...

 

CachedTypeResolver.cs:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Threading;

namespace Jint
{
    public class CachedTypeResolver : ITypeResolver
    {
        static Dictionary<string, Type> _Cache = new Dictionary<string, Type>();
        static ReaderWriterLock rwl = new ReaderWriterLock();
        ExecutionVisitor visitor;

        public CachedTypeResolver(ExecutionVisitor visitor)
        {
            this.visitor = visitor;
        }

        public Type ResolveType(string fullname)
        {
            rwl.AcquireReaderLock(Timeout.Infinite);

            try
            {
                if (_Cache.ContainsKey(fullname))
                {
                    return _Cache[fullname];
                }
                
                if (visitor.GlobalClrNamespace != null)
                {
                    if (_Cache.ContainsKey(visitor.GlobalClrNamespace + "." + fullname))
                    {
                        return _Cache[visitor.GlobalClrNamespace + "." + fullname];
                    }
                }
                
            }
            finally
            {
                rwl.ReleaseReaderLock();
            }

            Type type = null;
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
            {
                type = a.GetType(fullname, false, false);

                if (type != null)
                {
                    break;
                }
                if (visitor.GlobalClrNamespace != null)
                {
                    type = a.GetType(visitor.GlobalClrNamespace + "." + fullname, false, false);

                    if (type != null)
                    {
                        break;
                    }
                }

            }

            rwl.AcquireWriterLock(Timeout.Infinite);

            try
            {
                if (visitor.GlobalClrNamespace != null)
                    _Cache.Add(visitor.GlobalClrNamespace + "." + fullname, type);
                else
                    _Cache.Add(fullname, type);
                return type;
            }
            finally
            {
                rwl.ReleaseWriterLock();
            }
        }
    }
}