Skip to content

Commit

Permalink
💡 Add methods for C# scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
jxnkwlp committed Feb 7, 2024
1 parent 194f245 commit 62ccbb4
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public CSharpService(ILogger<CSharpService> logger, IMediator mediator, ICSharpS

public async Task<object> EvaluateAsync(string expression, Type returnType, ActivityExecutionContext context, Action<CSharpScriptEvaluationGlobal> globalConfigure = null, CancellationToken cancellationToken = default)
{
CSharpScriptEvaluationGlobal scriptEvaluationGlobal = new();
CSharpScriptEvaluationGlobal scriptEvaluationGlobal = new CSharpScriptEvaluationGlobal(_logger);

globalConfigure?.Invoke(scriptEvaluationGlobal);

Expand All @@ -40,7 +40,7 @@ public async Task<object> EvaluateAsync(string expression, Type returnType, Acti

_logger.LogDebug("Evaluate csharp code with id '{ScriptId}' ", scriptId);

CSharpScriptContext scriptContext = new(expression, scriptEvaluationGlobal, scriptConfigure.Reference.Assemblies, scriptConfigure.Reference.Imports)
CSharpScriptContext scriptContext = new(_logger, expression, scriptEvaluationGlobal, scriptConfigure.Reference.Assemblies, scriptConfigure.Reference.Imports)
{
ScriptId = scriptId,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using Elsa.Models;
using MediatR;
using Microsoft.Extensions.Logging;
using Passingwind.Abp.ElsaModule.Scripting.CSharp.Messages;
using Passingwind.CSharpScriptEngine;

Expand All @@ -21,13 +22,14 @@ public async Task<CSharpTypeDefinition> GenerateAsync(WorkflowDefinition workflo
{
var reference = new CSharpScriptReference();

StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();

sb.AppendLine("public static class Context { ");
sb = sb.AppendLine("public static class Context { ");

await _mediator.Publish(new CSharpTypeDefinitionNotification(workflowDefinition, sb, reference), cancellationToken);

sb.AppendLine("}");
sb = sb.AppendLine("}")
.AppendLine($"public static {typeof(ILogger)} Logger {{get; set;}}");

return new CSharpTypeDefinition
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Passingwind.Abp.ElsaModule.Scripting.CSharp.Messages;

namespace Passingwind.Abp.ElsaModule.Scripting.CSharp.Handlers;

public class CSharpScriptAbpAssembliesConfigureHandler : INotificationHandler<CSharpScriptConfigureNotification>
{
public Task Handle(CSharpScriptConfigureNotification notification, CancellationToken cancellationToken)
{
var reference = notification.Reference;

foreach (var item in Directory.GetFiles(AppContext.BaseDirectory, "Volo.*.dll"))
{
reference.Assemblies.Add(Assembly.LoadFile(item));
}

return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Passingwind.Abp.ElsaModule.Scripting.CSharp.Messages;

namespace Passingwind.Abp.ElsaModule.Scripting.CSharp.Handlers;

public class CSharpScriptElsaAssembliesConfigureHandler : INotificationHandler<CSharpScriptConfigureNotification>
{
public Task Handle(CSharpScriptConfigureNotification notification, CancellationToken cancellationToken)
{
var reference = notification.Reference;

foreach (var item in Directory.GetFiles(AppContext.BaseDirectory, "Elsa*.dll"))
{
reference.Assemblies.Add(Assembly.LoadFile(item));
}

return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ private async Task ConfigEngineGlobalAsync(CSharpScriptEvaluationGlobal global,
global.Context.WorkflowContext = context.GetWorkflowContext();

// Core functions
global.Context.GetService = (Action<Type>)((Type type) => context.ServiceProvider.GetService(type));
global.Context.GetRequiredService = (Action<Type>)((Type type) => context.ServiceProvider.GetRequiredService(type));
global.Context.GetService = (Func<Type, object>)((Type type) => context.ServiceProvider.GetService(type));
global.Context.GetRequiredService = (Func<Type, object>)((Type type) => context.ServiceProvider.GetRequiredService(type));

// Global functions.
global.Context.AddJournalData = (Action<string, object>)((string key, object value) => context.JournalData.Add(key, value));
Expand Down Expand Up @@ -127,7 +127,9 @@ private async Task AddActivityOutputAsync(CSharpScriptEvaluationGlobal global, A
var propertyName = property.Name;
var storageProviderName = storageProviderLookup.GetItem(propertyName) ?? property.DefaultWorkflowStorageProvider;

#pragma warning disable CA2012 // Use ValueTasks correctly
activityModel[propertyName] = () => _workflowStorageService.LoadAsync(storageProviderName, storageContext, propertyName, cancellationToken).Result;
#pragma warning restore CA2012 // Use ValueTasks correctly
}

activities[activity.Name!] = activityModel;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Passingwind.Abp.ElsaModule.Scripting.CSharp.Messages;

namespace Passingwind.Abp.ElsaModule.Scripting.CSharp.Handlers;

public class CSharpScriptCoreAssembliesConfigureHandler : INotificationHandler<CSharpScriptConfigureNotification>
{
public Task Handle(CSharpScriptConfigureNotification notification, CancellationToken cancellationToken)
{
var reference = notification.Reference;

reference.Assemblies.Add(Assembly.Load("Microsoft.Extensions.Logging.Abstractions"));
reference.Assemblies.Add(Assembly.Load("Microsoft.Extensions.Logging"));

reference.Imports.Add("Microsoft.Extensions.Logging");

return Task.CompletedTask;
}
}
3 changes: 2 additions & 1 deletion src/Passingwind.CSharpScript/CSharpScriptCompileContext.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Extensions.Logging;

namespace Passingwind.CSharpScriptEngine;

public class CSharpScriptCompileContext : CSharpScriptContext
{
public CSharpScriptCompileContext(string sourceText, CSharpScriptEvaluationGlobal? evaluationGlobal = null, List<Assembly>? assemblies = null, List<string>? imports = null) : base(sourceText, evaluationGlobal, assemblies, imports)
public CSharpScriptCompileContext(ILogger logger, string sourceText, CSharpScriptEvaluationGlobal? evaluationGlobal = null, List<Assembly>? assemblies = null, List<string>? imports = null) : base(logger, sourceText, evaluationGlobal, assemblies, imports)
{
}
}
5 changes: 3 additions & 2 deletions src/Passingwind.CSharpScript/CSharpScriptContext.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Extensions.Logging;

namespace Passingwind.CSharpScriptEngine;

public class CSharpScriptContext
{
public CSharpScriptContext(string sourceText, CSharpScriptEvaluationGlobal? evaluationGlobal = null, List<Assembly>? assemblies = null, List<string>? imports = null)
public CSharpScriptContext(ILogger logger, string sourceText, CSharpScriptEvaluationGlobal? evaluationGlobal = null, List<Assembly>? assemblies = null, List<string>? imports = null)
{
SourceText = sourceText;
EvaluationGlobal = evaluationGlobal ?? new CSharpScriptEvaluationGlobal();
EvaluationGlobal = evaluationGlobal ?? new CSharpScriptEvaluationGlobal(logger);
Assemblies = assemblies ?? new List<Assembly>();
Imports = imports ?? new List<string>();
}
Expand Down
15 changes: 10 additions & 5 deletions src/Passingwind.CSharpScript/CSharpScriptEvaluationGlobal.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
using System.Collections.Generic;
using System.Dynamic;
using Microsoft.Extensions.Logging;

namespace Passingwind.CSharpScriptEngine;

public class CSharpScriptEvaluationGlobal
{
public dynamic Context { get; }

public CSharpScriptEvaluationGlobal()
public ILogger Logger { get; }

public CSharpScriptEvaluationGlobal(ILogger logger)
{
Context = new ContextContainer();
Logger = logger;
logger.LogDebug("");
}

public void AddMember(string name, object value) => Context.AddMember(name, value);
public void AddVariable(string name, object value) => Context.AddMember(name, value);
public void AddMember(string name, object? value) => Context.AddMember(name, value);
public void AddVariable(string name, object? value) => Context.AddMember(name, value);

public class ContextContainer : DynamicObject
{
private static readonly Dictionary<string, object> _member = new();
private static readonly Dictionary<string, object?> _member = new();

public override bool TrySetMember(SetMemberBinder binder, object? value)
{
_member[binder.Name.ToLowerInvariant()] = value;
return true;
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
public override bool TryGetMember(GetMemberBinder binder, out object? result)
{
return _member.TryGetValue(binder.Name.ToLower(), out result);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
using NSubstitute;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Passingwind.CSharpScriptEngine;
using Shouldly;
using Xunit;
Expand All @@ -9,10 +8,12 @@ namespace Passingwind.Abp.ElsaModule;

public class CSharpScriptHostTests : ElsaModuleExtensionTestBase
{
private readonly ILogger _logger;
private readonly ICSharpScriptHost _cSharpScriptHost;

public CSharpScriptHostTests()
{
_logger = GetRequiredService<ILogger<CSharpScriptHostTests>>();
_cSharpScriptHost = GetRequiredService<ICSharpScriptHost>();
}

Expand All @@ -23,7 +24,7 @@ public async Task CompileTest1()
Console.WriteLine(""Hello, World!"");"
;
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(_logger, code));

result.Success.ShouldBeTrue();
}
Expand All @@ -34,7 +35,7 @@ public async Task CompileTest2()
const string code = @"
Console.WriteLine(""Hello, World!"");"
;
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(_logger, code));

result.Success.ShouldBeFalse();
}
Expand All @@ -49,7 +50,7 @@ public async Task CompileTest3()
"
;
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(_logger, code));

result.Success.ShouldBeTrue();
}
Expand Down Expand Up @@ -85,7 +86,7 @@ public async Task CompileTest4()
Console.WriteLine(u);
"
;
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.CompileAsync(new CSharpScriptCompileContext(_logger, code));

result.Success.ShouldBeTrue();
}
Expand Down Expand Up @@ -121,7 +122,7 @@ public async Task RunTest1()
Console.WriteLine(u);
"
;
var _ = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(code));
var _ = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(_logger, code));
}

[Fact]
Expand All @@ -134,7 +135,7 @@ public async Task RunTest2()
"
;
var result = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(_logger, code));

result.GetType().ShouldBe(typeof(string));
}
Expand All @@ -146,7 +147,7 @@ public async Task RunTest3()
return 1;
"
;
var result = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(code));
var result = await _cSharpScriptHost.RunAsync(new CSharpScriptCompileContext(_logger, code));

result.GetType().ShouldBe(typeof(int));
}
Expand Down

0 comments on commit 62ccbb4

Please sign in to comment.