| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
scriptcs has integrated support for NuGet packages. The integration is used for the following use cases.
The scriptcs model is based on a convention over configuration approach. Packages are not explicitly referenced within the script, instead the presence of a package locally means that it is automatically loaded / available.
There are 2 locations for packages in scriptcs.
Global packages live in ".\AppData\Local\ScriptCs\Packages". These packages contain scriptcs Modules. For example the FSharpModule is installed globally, and adds the ability for scriptcs to support using F#'s compiler / F# scripts.
Global packages are installed with scriptcs using scriptcs -install -g i.e. scriptcs -install ScriptCs.FSharp -g will install the FSharp module globally.
Global packages are automatically loaded when scriptcs starts up. We use MEF to scan the global packages for any [IModule] (https://github.com/scriptcs/scriptcs/blob/dev/src/ScriptCs.Contracts/IModule.cs) implementations. Any modules that are found are then invoked so they can configure scriptcs using the supplied module configuration object. Examples
Note: We are planning to change how global packages work in the near future. Once thes changes happen, scriptcs modules will not be installed globally, rather they will be installed at the app level. Global packages will still exist, but will only be used only for supporting CLI commands, similar to how node.js has global NPM packages.
App in this case is a folder with a bunch of scripts. A scriptcs App can have local packages installed. To install them the scriptcs -install command is used specifying the package name. On package installation, a scriptcs_packages.config file will be stored in the script folder. This is the packages.config file using NuGet's standard format. The packages themselves reside in a local scriptcs_packages folder.
Local packages are used for the following reasons:
At runtime (either in the REPL or running a script) we scan for the local scriptcs_packages.config file. If one is found, then we will look for the scriptcs_packages folder. If that is not found, we will automatically attempt to install the packages. Once the packages are installed (or if they exist) we will then automatically load them into memory. We use MEF to do this. We then use MEF to scan packages for Script Packs. Any that are found are initialized, allowing them to inject imports and references.
As mentioned earlier, packages are installed into scripts using the scriptcs -install command.
We rely on the NuGet.Core package by default to handle all our NuGet package resolution. We use it to query NuGet to get the packages that need to be installed and to do the actual installation.
One problem we have seen customers get into the past is having their app packages conflict with the versions scriptcs itself uses, or having conflicts within Script Packs due to the depending on an older version of our ScriptCs.Contracts assembly.
To mitigate this we have an AppDomainAssemblyResolver which overrides resolution at the App Domain level and automatically redirects assembly requests at runtime to the last version that is registered with the resolver. This doesn't solve binary conflict problems, but does solve versioning problems.
For example, let's assume a Script Pack (in a package) references ScriptCs.Contracts version 0.10, yet the person is running on ScriptCs version 0.13. At runtime when the Script Pack assembly requests for 0.10, it will get back 0.13 automatically.
All the services we use in scriptcs to install packages are pluggable and rely on contracts for which the default is NuGet. This gives us the ability to support other providers like Paket.
| Back | FazBrowse Home | New Git URL |