Giter Club home page Giter Club logo

Comments (6)

georgiosd avatar georgiosd commented on July 23, 2024

+1 on this one. At least the capability to unload the AppDomain and load it again

from cshell.

lukebuehler avatar lukebuehler commented on July 23, 2024

Good input, thanks.

The dll is locked by the underlying scripting engine. So we don't have much control over that. So shadow copying (what VS uses) is not really an option.

Running the scripting engine in a seperate AppDomain is a possibility. But it would make the interaction from the scripts with the UI much more cumbersome, since everything has to pass through MarshalByRefObjects or another serialization interface. Currently the scripting engine runs in the same AppDomain as the UI.

This is problem is REALLY annoying me too. Since at our company we have many CShell extensions and libraries that we work on daily and I have to always restart CShell whenver there's a change to our library. So, trust me, if I could easily fix this I would.

from cshell.

lukebuehler avatar lukebuehler commented on July 23, 2024

On second thoughts about closing this. I will not close it but just assign it into the far future.

from cshell.

georgiosd avatar georgiosd commented on July 23, 2024

I have a "free time" project where i ve integrated scriptcs with avalonedit and the completion sample. I ve managed to make it work on a different app domain but it took quite a different structure than cshell. Want me to go over the diffs? (I tried to base it on cshell initally but it proved too "complete" for me to get started)

Sent from a device with a small keyboard

On 12 Sep 2014, at 21:26, "Lukas Buhler" [email protected] wrote:

Good input, thanks.

The dll is locked by the underlying scripting engine. So we don't have much control over that. So shadow copying (what VS uses) is not really an option.

Running the scripting engine in a seperate AppDomain is a possibility. But it would make the interaction from the scripts with the UI much more cumbersome, since everything has to pass through MarshalByRefObjects or another serialization interface. Currently the scripting engine runs in the same AppDomain as the UI.

This is problem is REALLY annoying me too. Since at our company we have many CShell extensions and libraries that we work on daily and I have to always restart CShell whenver there's a change to our library. So, trust me, if I could easily fix this I would.


Reply to this email directly or view it on GitHub.

from cshell.

lukebuehler avatar lukebuehler commented on July 23, 2024

Yes, the devil is in the detail. In particular, it turned out to be difficult to have a tight integration between script code completion, REPL code completion, loaded libraries, and the scripting engine when running it all in a separate app domain.

I've tried to keep CShell as simple as possible in terms of architecture (maybe, turns out, a bit too simple), so that it has more of a hackers tool feel to it... Wanna unload the app domain? Just close and open the whole app... It's just difficult to stay simple without ending up re-implementing SharpDevelop/MonoDevelop/VisualStudio which are all much more mature projects of course.

I'd love to hear your input in how you designed it in your project!

from cshell.

georgiosd avatar georgiosd commented on July 23, 2024

Hey Luke!

Ok, here's my approach.

As you say, starting to implement either MarshalByRef or Serializable is a rabbit hole that you don't want to go down, especially when it comes to completion. So, instead, I separated the completion from the script engine. As far as I could tell, the only reason to have them mixed, was to maintain the same references/namespaces.

Here are the steps I took, not necessarily in this order:

  • Leave IScriptEngine alone and not inherit from it. Instead of your IReplExecutor, I made a new interface IRepl that is constructed with the script engine (allowing any ScriptCs engine to be used too). It's pretty simple: a script engine getter, a command-aware Execute() (which accepts my own command interface as I found the ScriptCs one limiting), getters for variables/namespaces/refs and Terminate(). Note that Execute() will return my own ReplScriptResult that contains only serializiable types:
[Serializable]
    public class ReplScriptResult
    {
        public string[] Messages { get; private set; }

        public bool IsCompleteSubmission { get; private set; }

        public string ReturnValueAsString { get; private set; }

        public ReplScriptResult(ScriptResult result)
        {
            IsCompleteSubmission = result.IsCompleteSubmission;

            Messages = GetMessages(result);

            ReturnValueAsString = ToPrettyString(result.ReturnValue);
        }

        private static string[] GetMessages(ScriptResult scriptResult)
        {
            var msgs = new List<string>();

            if (scriptResult.CompileExceptionInfo != null)
            {
                var ex = scriptResult.CompileExceptionInfo.SourceException;
                msgs.Add(ex.Message);
            }

            if (scriptResult.ExecuteExceptionInfo != null)
            {
                var ex = scriptResult.ExecuteExceptionInfo.SourceException;
                msgs.Add(ex.ToString());
            }

            return msgs.ToArray();
        }

        private static string ToPrettyString(object o)
        {
            if (o == null)
                return "null";

            if (o is String)
                return o.ToString();

            var enumerable = o as IEnumerable;
            if (enumerable != null)
            {
                var items = enumerable.Cast<object>().Take(21).ToList();
                var firstItems = items.Take(20).ToList();
                var sb = new StringBuilder();
                sb.Append("{");
                sb.Append(String.Join(", ", firstItems));
                if (items.Count > firstItems.Count)
                    sb.Append("...");
                sb.Append("}");
                return sb.ToString();
            }

            return o.ToString();
        }
    }
  • Use ObservableCollection<T> to contain the refs/namespaces - this allows the completion engine to be notified of additions and updates its own collection.
  • There is also an IReplFactory which does the obvious. Both the implementations of IRepl and IReplFactory inherit from MarshalByRef so that they can be created in the new AppDomain
  • I also introduced an ICompletionProvider which also does the obvious - provides completion results either based on the default document or based on the IRepl. Always constructed on the UI AppDomain.
  • Finally, I have my ReplControl WPF control which has a dependency property Repl of type IRepl. The view model maintains the app domain and has a Reset() command that will create a new app domain+factory and then assign a new IRepl to the bound property. When the dependency property is set, I then create a new ReplCompletionProvider

How's it sound?

from cshell.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.