-
Notifications
You must be signed in to change notification settings - Fork 4
Разработка классов
[TOC]
На данной странице приведен пример создания нового класса, который можно потом использовать в скриптах.
Класс представляет собой так называемый "контекст", а задача создания класса, как правило, сводится к добавлению в проект обычного класса C# и применения специальных атрибутов к его членам.
В принципе, для реализации класса нужно реализовать у него интерфейсы IValue и IRuntimeContextInstance. Однако, есть упрощенный вариант. Именно он и рассматривается ниже.
Все прикладные классы реализуются в сборке ScriptEngine.HostedScript в папке Library.
Вам нужно добавить обычный новый класс C#, дать ему какое-то имя %ВашеИмя% и унаследовать его от класса AutoContext<%ВашеИмя%>. Кроме того, класс нужно пометить атрибутом ContextClassAttribute.
#!c#
using System;
using System.IO;
using ScriptEngine.Machine;
using ScriptEngine.Machine.Contexts;
namespace ScriptEngine.Machine.Library
{
[ContextClass("ЧтениеТекста", "TextReader")]
class TextReadImpl : AutoContext<TextReadImpl>, IDisposable
{
StreamReader _reader;
[ContextMethod("Открыть", "Open")]
public void Open(string path, string encoding = null)
{
if (encoding == null)
{
_reader = Environment.FileOpener.OpenReader(path);
}
else
{
var enc = Encoding.GetEncoding(encoding);
_reader = Environment.FileOpener.OpenReader(path, enc);
}
}
}
В примере приведен фрагмент класса TextReadImpl, который в языке виден, как ЧтениеТекста. Класс унаследован от AutoContext и помечен атрибутом ContextClassAttribute.
В принципе, этих простых действий достаточно, чтобы ваш класс появился в языке.
В приведенном примере класс не имеет конструктора. Экземпляр такого класса нельзя создать через оператор Новый, однако его можно вернуть, как результат какого-либо метода.
Чтобы экземпляры класс могли создаваться через оператор Новый, нашему классу нужно задать конструкторы. Конструктор реализуется в виде статического метода класса, помеченного атрибутом ScriptConstructorAttribute и возвращающего IRuntimeContextInstance.
#!c#
[ScriptConstructor(Name="По имени файла и кодировке")]
public static IRuntimeContextInstance Constructor(IValue path, IValue encoding)
{
var reader = new TextReadImpl();
reader.Open(path.AsString(), encoding.AsString());
return reader;
}
Методы класса - это обычные методы-члены класса C#, которые помечены атрибутом ContextMethodAttribute.
Типы параметров автоматически транслируются из типов языка 1С в типы языка C#
#!c#
[ContextMethod("Открыть", "Open")]
public void Open(string path, string encoding = null)
{
if (encoding == null)
{
_reader = Environment.FileOpener.OpenReader(path);
}
else
{
var enc = Encoding.GetEncoding(encoding);
_reader = Environment.FileOpener.OpenReader(path, enc);
}
}
Обратите внимание, параметры заявлены, как string. OneScript самостоятельно транслирует типы значений, передаваемых из скрипта в методы C# и выбрасывает исключения, если типы несовместимы.
Если метод имеет выходной параметр (возвращает значение в параметре), то этот параметр должен иметь тип IVariable и быть помечен атрибутом ByRefAttribute. Т.е. это должно выглядеть примерно так:
#!c#
[ContextMethod("Свойство", "Property")]
public bool HasProperty(string name, [ByRef] IVariable value = null)
{
value.Value = ValueFactory.Create("Это строковое значение, передаваемое в скрипт");
}
Второй параметр value
является необязательным и в нем можно вернуть значение обратно в скрипт.
Свойство класса - это обычное свойство класса C#, помеченное атрибутом ContextPropertyAttribute.
#!c#
[ContextProperty("Имя","Name")]
public string Name
{
get
{
return "some name";
}
}
Доступность чтения и записи свойства регулируется двумя способами:
- Обычная видимость get/set элементов свойства
- Параметры CanRead/CanWrite атрибута ContextPropertyAttribute
В приведенном примере свойство не содержит части set, поэтому оно будет доступно в скриптах только, как свойство "Для чтения". Если добавить туда часть set, то свойство будет доступно для записи.
1Script самостоятельно регистрирует в системе доступность свойств и автоматически транслирует типы значений языка 1С в типы C# и обратно.
Чтобы добавить свой класс в язык, вам нужно:
- Создать обычный класс C#
- Пометить его атрибутом ContextClass
- Унаследовать его от AutoContext<ИмяВашегоКласса>
- Пометить нужные свойства класса атрибутом ContextProperty
- Пометить нужные методы класса атрибутом ContextMethod
- Создать статический метод для конструктора и пометить его атрибутом ScriptConstructor
- Все, ваш класс теперь можно использовать в сценариях.