您可以编写自定义 OCL 操作。这里有一个例子:
[EcoOclOperation(typeof(OclEcoId), true)]
public class OclEcoId : OclOperationBase
{
/// <summary>
/// Initialisation of the OCL funktion
/// </summary>
protected override void Init()
{
var parameter = new IOclType[1]
{
this.Support.ObjectType,
};
this.InternalInit("EcoId", parameter, this.Support.IntegerType);
}
/// <summary>
/// Implementation of the OCL function
/// </summary>
/// <param name="parameters">OCL parameters</param>
public override void Evaluate(IOclOperationParameters parameters)
{
var iObject = parameters.Values[0].Element as IObject;
if (iObject != null && iObject.AsObject != null)
{
var ecoid = iObject.EcoID();
this.Support.MakeNewInteger(parameters.Result, int.Parse(ecoid));
}
}
}
这样的操作必须像这样安装到 EcoSpace 中:
public static class OclInstaller
{
/// <summary>
/// InstallOclOperations
/// </summary>
/// <param name="ecoSpace">The EcoSpaceparam>
public static void InstallOclOperations(EcoSpace ecoSpace)
{
if (ecoSpace != null)
{
var ocls = ecoSpace.GetEcoService<IOclService>();
var eals = ecoSpace.GetEcoService<IActionLanguageService>();
// Install all available operations in current assembly
foreach (Type t in System.Reflection.Assembly.GetAssembly(typeof(OclInstaller)).GetTypes())
{
if (t.BaseType == typeof(OclOperationBase))
{
var op = (OclOperationBase)Activator.CreateInstance(t);
eals.InstallOperation(op);
object[] attributes = t.GetCustomAttributes(typeof(EcoOclOperationAttribute), false);
if (attributes.Length == 1)
{
if ((attributes[0] as EcoOclOperationAttribute).IsQuery)
{
ocls.InstallOperation(op);
}
}
else
{
ocls.InstallOperation(op);
}
}
}
}
else
{
throw new NullReferenceException("Error in [InstallOclOperations]: EcoSpace is null.");
}
}
}
在 ecospace 的构造函数中调用此安装程序:
OclInstaller.InstallOclOperations(this);
令人惊讶的是,使用 MDriven 添加新的自定义 OCL 操作是多么容易。正如 Hans 所说,开箱即用评估 OCL 是不可能的,但您可以编写自己的评估器。但请退后一步,对实现功能的方式做出适当的架构决定。
您也可以添加自定义生态服务,但这是完全不同的故事。