Я решил эту проблему, добавив настройки клонирования в конвейеры Bitbucket. Я не уверен, почему это работает, но я добавил это прежде, чтобы решить это, но удалил это некоторое время назад. Я снова начал получать эту проблему, поэтому добавление ее решило проблему. Но предупреждение состоит в том, что это может немного замедлить ваше развертывание, так как git сделает полный клон в контейнере конвейеров. Вот мой фрагмент конфигурации bitbucket-pipelines.yml. Это просто подталкивает к лазурному развертыванию git url. Добавление «глубина клона: полная» разрешает это для меня:
image: python:2.7.13
clone:
depth: full
pipelines:
branches:
master:
- step:
script:
- git push "https:/...
как другие уже упомянул не действительно возможный скомпилировать c# в оценке () функция. та функциональность настругана для последнего выпуска сброса, который anders продемонстрировал в PDC.
как другой solutionm, если Ваше приложение может работать моно, можно просто использовать его функцию оценки, которая может динамично скомпилировать код c#, точно так же, как JavaScript. это - basicly, уже делающий, что .NET сможет сделать через год или два.
как альтернатива при наклонении использования, моно, Вы могли бы записать часть, которая делает обработку строк в ironruby, который имеет оценку (). остальная часть Вашей привычки кода даже знает об использовании рубина для этого class/assambly.
ссылка Вы отправили во взглядах обновления, довольно сложных для такого простого варианта использования. использование ironruby все, что необходимо было бы сделать, записать MyDynamicEvalClass что-то вроде этого:
class MyDynamicEvalClass
def eval(someString,transformString)
eval(someString,transformString)
end
end
и замена "ManipulationSetting" с некоторым кодом Ruby, который возвращает новую строку
Это не tooo трудно ;) Я соединил немного примера. Это должно помочь Вам решить, хотите ли Вы использовать динамические сценарии.. или regexes.
То, что можно сделать, создают интерфейс в блоке, который реализует динамический код:
namespace CompileScriptExample
{
public interface IStringManipulator
{
string processString(string aString);
}
}
Затем создайте класс ScriptRunner:
namespace CompileScriptExample
{
public class ScriptRunner
{
public static string RunScript(string scriptCode, string scriptParameter)
{
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
//configure parameters
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.IncludeDebugInformation = false;
string reference;
// Set reference to current assembly - this reference is a hack for the example..
reference = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
parameters.ReferencedAssemblies.Add(reference+"\\CompileScriptExample.exe");
//compile
CompilerResults results = provider.CompileAssemblyFromSource(parameters, new string[] { scriptCode });
if (results.Errors.Count == 0)
{
IStringManipulator compiledScript=(IStringManipulator)FindInterface(results.CompiledAssembly, "IStringManipulator");
return compiledScript.processString(scriptParameter);//run the script, pass the string param..
}
else
{
foreach(CompilerError anError in results.Errors)
{
MessageBox.Show(anError.ErrorText);
}
//handle compilation errors here
//..use results.errors collection
throw new Exception("Compilation error...");
}
}
private static object FindInterface(Assembly anAssembly, string interfaceName)
{
// find our interface type..
foreach (Type aType in anAssembly.GetTypes())
{
if (aType.GetInterface(interfaceName, true) != null)
return anAssembly.CreateInstance(aType.FullName);
}
return null;
}
}
}
Теперь все, что необходимо сделать, создают строку сценария с кодом, который реализует интерфейс как..
string myScriptString=@"using CompileScriptExample;
public class MyStringManipulator : IStringManipulator
{
public string processString(string aString)
{
return aString+aString;
}
};
и затем.. в Вашем коде используйте ScriptRunner для обработки строки с динамическим кодом:
string processedString = ScriptRunner.RunScript(myScriptString, "hello");
Я знаю, что Вы после того, как C#, но код я имею для этого, находится в VB. Вы могли перевести его достаточно легко использование VB Fusion Разработчика к преобразователю C#. Я использовал его на проекте позволить пользователям добавлять сложные вычисления в свое приложение во времени выполнения. Это компилирует их код VB в библиотеку в памяти и затем выполняет код, возвращая получающийся вывод. Это могло повторно ставиться целью довольно легко для того, что Вы пытаетесь сделать.
Imports System.Reflection
Imports System.CodeDom.Compiler
Imports System.Text.RegularExpressions
Imports System.Math
Module Module1
Function Evaluate(ByVal Expression As String, ByVal Args() As Object) As Object
If Expression.Length > 0 Then
'Replace each parameter in the calculation expression with the correct values
Dim MatchStr = "{(\d+)}"
Dim oMatches = Regex.Matches(Expression, MatchStr)
If oMatches.Count > 0 Then
Dim DistinctCount = (From m In oMatches _
Select m.Value).Distinct.Count
If DistinctCount = Args.Length Then
For i = 0 To Args.Length - 1
Expression = Expression.Replace("{" & i & "}", Args(i))
Next
Else
Throw New ArgumentException("Invalid number of parameters passed")
End If
End If
Dim FuncName As String = "Eval" & Guid.NewGuid.ToString("N")
Dim FuncString As String = "Imports System.Math" & vbCrLf & _
"Namespace EvaluatorLibrary" & vbCrLf & _
" Class Evaluators" & vbCrLf & _
" Public Shared Function " & FuncName & "() As Double" & vbCrLf & _
" " & Expression & vbCrLf & _
" End Function" & vbCrLf & _
" End Class" & vbCrLf & _
"End Namespace"
'Tell the compiler what language was used
Dim CodeProvider As CodeDomProvider = CodeDomProvider.CreateProvider("VB")
'Set up our compiler options...
Dim CompilerOptions As New CompilerParameters()
With CompilerOptions
.ReferencedAssemblies.Add("System.dll")
.GenerateInMemory = True
.TreatWarningsAsErrors = True
End With
'Compile the code that is to be evaluated
Dim Results As CompilerResults = _
CodeProvider.CompileAssemblyFromSource(CompilerOptions, FuncString)
'Check there were no errors...
If Results.Errors.Count > 0 Then
Else
'Run the code and return the value...
Dim dynamicType As Type = Results.CompiledAssembly.GetType("EvaluatorLibrary.Evaluators")
Dim methodInfo As MethodInfo = dynamicType.GetMethod(FuncName)
Return methodInfo.Invoke(Nothing, Nothing)
End If
Else
Return 0
End If
Return 0
End Function
End Module
Я установил свой динамический кодекс как это:
Dim Expr As String = " If ({0} < 20000) Then" & vbCrLf & _
" Return Max(15, Min(75,0.12*{0}))" & vbCrLf & _
" Else" & vbCrLf & _
" Return Max(75,0.05*{0})" & vbCrLf & _
" End If"
И затем настроенный некоторые аргументы в пользу выражения и выполнитесь:
Dim Args As New List(Of String)
While True
Dim Val As String = Console.ReadLine
Args.Clear()
If IsNumeric(Val) Then
Args.Add(Val)
Dim dblOut As Object = Evaluate(Expr, Args.ToArray)
Console.WriteLine(dblOut)
Else
Exit While
End If
End While
Я думаю, что это - возможное использование reflection.emit и codedom, чтобы сделать это, но это нисколько не тривиально, и я отговариваю от него.
Как альтернатива, Вы могли попытаться настроить строку формата, возможно в дополнение к regex.
В то время как Вы могли использовать перечисление для указания на действие, Вы хотите взять, или использовать CodeDom для испускания кода динамично, к чему это сводится, то, что Вы хотите определить преобразование некоторого вида, что означает, что у Вас есть исходные данные и вывод.
Выяснение вывода легко в этом случае, у Вас есть строка. Для исходных данных казалось бы, что у Вас может быть переменное количество исходных данных. Это было бы определено как IEnumerable<string>
.
Имея это в виду, можно определить интерфейс как так:
public interface IStringManipulation
{
string Manipulate(IEnumerable<string> parameters);
}
Затем было бы легко определить реализации этого типа и затем поместить имена типов в Вашу конфигурацию.
Вы действительно хотите сделать это вместо того, чтобы динамично компилировать код от строк. В использовании строк у Вас есть большая гибкость, да, но Вы не имеете никакого времени компиляции, проверяя и открываете себя до ошибок и проблем безопасности.
Кроме того, время, которое это собирается занять для записи части кода для испускания кода на основе строкового фрагмента, который Вы обеспечиваете, будет довольно утомительным также, поскольку необходимо создать блок, класс, метод, затем скомпилируйте и затем назовите метод, который Вы компилируете динамично посредством отражения (если у Вас нет его, реализуют интерфейс, в этом случае, Вы могли бы также сделать то, что я предлагаю так или иначе).
Я просто натыкался на что-то на днях, которое делает просто это на другом языке.NET: http://reverseblade.blogspot.com/2009/02/dont-wait-for-c-5-use-nemerle.html
Я предположил бы, что Вы могли записать свой строковый код обработки в nemerle, скомпилировать, и ссылка от Вашего C# или приложения VB.
Я все еще одобрил бы расширяемый дизайн как casperOne, предлагает. Путем выполнения динамических сценариев Вы будете просто продвигать компиляцию в приложение, и развертывание в любой процесс получает строки программирования к приложению. Но это кажется, что у Вас есть свои причины, таким образом, единственной другой вещью, которую я рассмотрел бы здесь, является безопасность. Идеально, Вы хотите ограничить пользователя как можно больше только к управлению строками, в этом случае List-of-Regex походит на довольно хороший вариант.