in src/FunctionInfo.cs [51:149]
internal AzFunctionInfo(RpcFunctionMetadata metadata)
{
FuncName = metadata.Name;
FuncDirectory = metadata.Directory;
EntryPoint = metadata.EntryPoint;
ScriptPath = metadata.ScriptFile;
// Support 'entryPoint' only if 'scriptFile' is a .psm1 file;
// Support .psm1 'scriptFile' only if 'entryPoint' is specified.
bool isScriptFilePsm1 = ScriptPath.EndsWith(".psm1", StringComparison.OrdinalIgnoreCase);
bool entryPointNotDefined = string.IsNullOrEmpty(EntryPoint);
if (entryPointNotDefined)
{
if (isScriptFilePsm1)
{
throw new ArgumentException(PowerShellWorkerStrings.RequireEntryPointForScriptModule);
}
}
else if (!isScriptFilePsm1)
{
throw new ArgumentException(PowerShellWorkerStrings.InvalidEntryPointForScriptFile);
}
// Get the parameter names of the script or function.
var psScriptParams = GetParameters(ScriptPath, EntryPoint, out ScriptBlockAst scriptAst);
FuncParameters = new ReadOnlyDictionary<string, PSScriptParamInfo>(psScriptParams);
var parametersCopy = new Dictionary<string, PSScriptParamInfo>(psScriptParams, StringComparer.OrdinalIgnoreCase);
HasTriggerMetadataParam = parametersCopy.Remove(TriggerMetadata);
HasTraceContextParam = parametersCopy.Remove(TraceContext);
HasRetryContextParam = parametersCopy.Remove(RetryContext);
var allBindings = new Dictionary<string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase);
var inputBindings = new Dictionary<string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase);
var outputBindings = new Dictionary<string, ReadOnlyBindingInfo>(StringComparer.OrdinalIgnoreCase);
DurableFunctionInfo = DurableFunctionInfoFactory.Create(metadata.Bindings);
var inputsMissingFromParams = new List<string>();
foreach (var binding in metadata.Bindings)
{
string bindingName = binding.Key;
var bindingInfo = new ReadOnlyBindingInfo(binding.Value);
allBindings.Add(bindingName, bindingInfo);
if (bindingInfo.Direction == BindingInfo.Types.Direction.In)
{
inputBindings.Add(bindingName, bindingInfo);
// If the input binding name is in the set, we remove it;
// otherwise, the binding name is missing from the params.
if (!parametersCopy.Remove(bindingName)
&& !DurableBindings.CanParameterDeclarationBeOmitted(bindingInfo.Type))
{
inputsMissingFromParams.Add(bindingName);
}
}
else if (bindingInfo.Direction == BindingInfo.Types.Direction.Out)
{
outputBindings.Add(bindingName, bindingInfo);
}
else
{
// PowerShell doesn't support the 'InOut' type binding
throw new InvalidOperationException(string.Format(PowerShellWorkerStrings.InOutBindingNotSupported, bindingName));
}
}
if (inputsMissingFromParams.Count != 0 || parametersCopy.Count != 0)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (string inputBindingName in inputsMissingFromParams)
{
stringBuilder.AppendFormat(PowerShellWorkerStrings.MissingParameter, inputBindingName).AppendLine();
}
foreach (string param in parametersCopy.Keys)
{
stringBuilder.AppendFormat(PowerShellWorkerStrings.UnknownParameter, param).AppendLine();
}
string errorMsg = stringBuilder.ToString();
throw new InvalidOperationException(errorMsg);
}
if (entryPointNotDefined && scriptAst.ScriptRequirements == null)
{
// If the function script is a '.ps1' file that doesn't have '#requires' defined,
// then we get the script block and will deploy it as a PowerShell function in the
// global scope of each Runspace, so as to avoid hitting the disk every invocation.
FuncScriptBlock = scriptAst.GetScriptBlock();
DeployedPSFuncName = $"_{FuncName}_";
}
AllBindings = new ReadOnlyDictionary<string, ReadOnlyBindingInfo>(allBindings);
InputBindings = new ReadOnlyDictionary<string, ReadOnlyBindingInfo>(inputBindings);
OutputBindings = new ReadOnlyDictionary<string, ReadOnlyBindingInfo>(outputBindings);
}