How do I get started designing and implementing a script interface for my .NET application?

不羁岁月 提交于 2019-12-03 03:42:08

问题


How do I get started designing and implementing a script interface for my .NET application?

There is VSTA (the .NET equivalent of VBA for COM), but as far as I understand I would have to pay a license fee for every installation of my application. It is an open source the application so this will not work.

There is also e.g. the embedding of interpreters (IronPython?), but I don't understand how this would allow exposing an "object model" (see below) to external (or internal) scripts.

Sub-questions:

  • What is the scripting interface story in .NET? Is it somehow trivial to do this in .NET?
  • E.g. can some .NET objects in my application and their contained objects be declared to be accessible from the outside at runtime?
  • How can external scripts access my application (through the object model)?

Background:

I have once designed and implemented a fairly involved script interface for a Macintosh application for acquisition and analysis of data from a mass spectrometer (Mac OS, System 7) and later a COM interface for a Windows application.

Both were designed with an "object model" and classes (that can have properties). These are overloaded words, but in a scripting interface context object model is essentially a containment hierarchy of objects of specific classes. Classes have properties, lists of contained objects and are not only data but can have verbs as well (actions/methods). E.g. in the Macintosh case the defined application object can contain an acquisition object that has properties for voltages used in the instrument and a fireLater verb - all as seen from the external script.

Note that in both cases the classes/objects in the programming language used to implement the application had nothing to do with the scripting object model. For the Macintosh case, the mechanisms used to implement the scripting interface was defined by Apple. There were also some standards defined by Apple on how to design the object model. For instance, standardized names for certain common properties in classes.

Or like in the COM interfaces exposed in Microsoft Office applications, where the application object can be used to add to its list of documents (with the side effect of creating the GUI representation of a document).

External scripts can create new objects in a container and navigate through the content of the hierarchy at any given time. In the Macintosh, case scripts could be written in e.g. AppleScript or Frontier.

On the Macintosh, the implementation of a scripting interface was very complicated. Support for it in Metroworks' C++ class library (the name escapes me right now) made it much simpler.


回答1:


[EDIT: As covered at length in the comments in this, assuming you have a significant need to enable internal scripting where you are hosting snippets or functions someone gives you to customise your app, as opposed to a purely external scenario where one is providing a facaade to allow people to dig stuff out of your app on a more rigid predefined basis]

IronRuby and IronPython are very neat and appropriate for this (but as the other answer says, PowerShell may be appropriate if you have a more infrastructure-type thing).

EDIT: Other ideas for enabling internal scripting are

  • using Windows Workflow Foundation (exposing activities to it and/or hosting instances of workflows)
  • using Spring.NET's Expression Language (which is terse, easy to doc and learn but surprisingly powerful)

EDIT 2 June 2011: IronJS may also be a suitable candidate, there's a Hanselminutes that talks it thru.




回答2:


Take a look at PowerShell.

It allows you to program simple Cmdlets that are scriptable. It also supports hierachical containers (by default you have the file system, the Registry, certificates store, etc.).




回答3:


I would suggest you consider the Dynamic Language Runtime as a strategy for implementing a scripting interface. Details:

  • CodePlex DLR site
  • MSDN .NET 4 DLR Overview

The DLR currently supports IronPython and IronRuby, plus a number of other language implementations can be found on CodePlex. If you are interested in creating a language specific to your application Bitwise Magazine has a good primer article.

Dino Viehland's PDC09 session Using Dynamic Languages to Build Scriptable Applications is worth watching. You can find the demo code here.




回答4:


The Lua scripting language is free, used in a large number of commercial applications, and is easily embeddable into a .NET application using the freely-available LuaInterface library, which permits you to expose types and methods from your application that scripts in your embedded interpreter can leverage.

A tutorial on how to embed Lua into a C# application can be found here.

Edit: It's probably also worth noting that Lua was designed from the ground up to be an embedded scripting language, and as a result, the interpreter is highly customizable. The host application can restrict almost any aspect of the interpretation capabilities as part of the security model; e.g. allowing or preventing scripts from making network connections or writing to files, etc.

Also, you asked about external scripts. Making your program available to out-of-process scripts is done in the same way you make it available to out-of-process applications: by exposing a standardized automation interface through some sort of communication protocol. On Windows, for same-machine cross-process communication, that will most commonly be COM, but it could also be WCF, TCP remoting, RPC or any number of other communications standards. What you choose to do depends heavily on how your application is built and what kind of external automation you intend for it to do.




回答5:


I used CS-Script to create something like you want. In my case I defined an interface in my application. A script then just needed to implement this interface so that it could be run from the application. My application was about processing scanned images and therefore my interface looked something like this:

public interface ICustomModule
{
    void ProcessBatch(IBatch batch)
}

This way my script could access the object model that I defined in my application (in my case through IBatch). The good thing was that during development I could use a normal Class Library project for the script: IntelliSense, debugging... I do not remember the exact details but I basically had a switch in my application that told the app to use the referenced class library instead of a script.

Furthermore I made an additional interface that allowed the scripts to be configured: A script could define a set of properties which were then displayed by my application in a property grid. I think I used this version here as this seemed a bit more flexible at the time. This way you can not only allow users to configure the script, but you can also provide help in form of descriptions, choices, default values... The property grid is quite extensible: In one case we had a script that would display a special form to define some complex settings.

Edit: The application of course did not have a reference to "debug" class library. It just need to load the assembly...




回答6:


For a free, easy to implement .NET scripting language, have a look at C#.

See my answer to a similar question.

As for exposing data, seeing how it's a .NET language, you just need to add your program into the assemblies to link into and make the relevant classes public.




回答7:


I'm not sure this will cover your needs, but via reflection you can compile C# code and execute it at runtime (example code here).

So you could write the script in eg. C# and then compile "it on the fly" and run it directly in the context of your application. Of course you have to keep security considerations in mind, but if the scripts are trusted then it might work for you, and you get the benefits of using a powerful managed language for your scripts.

If you need high performance or running thousands of scripts it might be too slow though.




回答8:


I implemented CS-Script as the scripting platform last for a workflow system I wrote. Each wrokflow needed had different conditions that dictated what users would subscribe to various tasks and who would receive emails. With a scripting model it became easy to introduce new steps into the workflows and handle unique requirements that those tasks required.

The other nice by product of the scripting model was that workflows could be tested under a variety of conditions, and an iterative approach could be taken to finalize the workflow behaviors. During QA and user acceptance testing I included logging functions in the scripts to that I could hunt issues more easily.

With CS-Script you have complete access to you objects; that is, when your script imports your assemblies you can instantiate your object in your script code. Furthermore, you can retain your compiled scripts and simply supply parameters to them. If your assemblies use a parameters object or a Dictionary, you can pass that your script and execute methods on the objects contained in the parameter object.



来源:https://stackoverflow.com/questions/2402989/how-do-i-get-started-designing-and-implementing-a-script-interface-for-my-net-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!