refactoring build for 3.0; using Mono.Cecil for attribute discovery

This commit is contained in:
Brett Samblanet 2019-11-14 14:34:07 -08:00
Родитель ca38d6b097
Коммит 74446334e6
33 изменённых файлов: 303 добавлений и 710 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -42,6 +42,7 @@ dlldata.c
# DNX
project.lock.json
launchSettings.json
artifacts/
*_i.c

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26927.3000
# Visual Studio Version 16
VisualStudioVersion = 16.0.29509.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{14D6456E-2F9D-4483-A378-03701A6EB12D}"
EndProject
@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions.Generator", "src\Microsoft.NET.Sdk.Functions.Generator\Microsoft.NET.Sdk.Functions.Generator.csproj", "{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Functions.NETStandard", "src\Microsoft.NET.Sdk.Functions.NETStandard\Microsoft.NET.Sdk.Functions.NETStandard.csproj", "{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{03DEE129-17B6-4CE0-B2D8-5B648D5BEE64}"
ProjectSection(SolutionItems) = preProject
build.cmd = build.cmd
@ -45,10 +43,6 @@ Global
{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35}.Release|Any CPU.Build.0 = Release|Any CPU
{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC}.Release|Any CPU.Build.0 = Release|Any CPU
{B80DA350-8A69-4CD2-9E60-01C51B5A8633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B80DA350-8A69-4CD2-9E60-01C51B5A8633}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B80DA350-8A69-4CD2-9E60-01C51B5A8633}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -65,7 +59,6 @@ Global
{9D59910B-B90E-4BBE-BD26-C2CBF85D37E1} = {9B6D0171-3FFD-4892-B407-B633CA4E6712}
{5DCBB929-5248-4701-82C9-88BB566E404C} = {8D555953-A625-4C7F-93A7-C737644820AB}
{6CEDE940-9F0A-4B2A-97D4-D1EEEE42AF35} = {14D6456E-2F9D-4483-A378-03701A6EB12D}
{14DF7D60-3AE6-4A5C-A2FF-BE49720DDFEC} = {14D6456E-2F9D-4483-A378-03701A6EB12D}
{B80DA350-8A69-4CD2-9E60-01C51B5A8633} = {9B6D0171-3FFD-4892-B407-B633CA4E6712}
{1DB38EB5-DBA9-4678-BB99-2BCD1255DDBE} = {14D6456E-2F9D-4483-A378-03701A6EB12D}
EndGlobalSection

Просмотреть файл

@ -1,2 +1,4 @@
powershell Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile '%TEMP%\dotnet-install.ps1'
powershell %TEMP%\dotnet-install.ps1 -Architecture x64 -Version '3.0.100' -InstallDir '%ProgramFiles%\dotnet'
.paket\paket.exe install
packages\FAKE\tools\fake .\build.fsx

Просмотреть файл

@ -58,21 +58,14 @@ Target "Build" (fun _ ->
)
Target "GenerateZipToSign" (fun _ ->
!! (packOutputPath @@ "net46\\Microsoft.NET.Sdk.Functions.dll")
++ (buildTaskOutputPath @@ "net46\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
++ (generatorOutputPath @@ "net461\\Microsoft.NET.Sdk.Functions.Generator.exe")
|> CreateZip "." (version + "net46.zip") "" 7 true
!! (generatorOutputPath @@ "net461\\Newtonsoft.Json.dll")
|> CreateZip "." (version + "net46thirdparty.zip") "" 7 true
!! (packOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.dll")
++ (buildTaskOutputPath @@ "netstandard1.5\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
++ (generatorOutputPath @@ "netcoreapp2.1\\Microsoft.NET.Sdk.Functions.Generator.dll")
++ (buildTaskOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
++ (generatorOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.Generator.dll")
|> CreateZip "." (version + "netstandard2.zip") "" 7 true
!! (generatorOutputPath @@ "netcoreapp2.1\\Newtonsoft.Json.dll")
|> CreateZip "." (version + "netstandard2thidparty.zip") "" 7 true
!! (generatorOutputPath @@ "netcoreapp3.0\\Newtonsoft.Json.dll")
++ (generatorOutputPath @@ "netcoreapp3.0\\Mono.Cecil.dll")
|> CreateZip "." (version + "netstandard2thirdparty.zip") "" 7 true
)
let storageAccount = lazy CloudStorageAccount.Parse connectionString
@ -104,30 +97,17 @@ let rec DownloadFile fileName (startTime: DateTime) = async {
return! DownloadFile fileName startTime
}
Target "UploadZipToSign" (fun _ ->
UploadZip (version + "net46.zip")
UploadZip (version + "net46thirdparty.zip")
Target "UploadZipToSign" (fun _ ->
UploadZip (version + "netstandard2.zip")
UploadZip (version + "netstandard2thidparty.zip")
UploadZip (version + "netstandard2thirdparty.zip")
)
Target "EnqueueSignMessage" (fun _ ->
EnqueueMessage ("Sign;azure-functions-build-sdk;" + (version + "net46.zip"))
EnqueueMessage ("Sign3rdParty;azure-functions-build-sdk;" + (version + "net46thirdparty.zip"))
Target "EnqueueSignMessage" (fun _ ->
EnqueueMessage ("Sign;azure-functions-build-sdk;" + (version + "netstandard2.zip"))
EnqueueMessage ("Sign3rdParty;azure-functions-build-sdk;" + (version + "netstandard2thidparty.zip"))
EnqueueMessage ("Sign3rdParty;azure-functions-build-sdk;" + (version + "netstandard2thirdparty.zip"))
)
Target "WaitForSigning" (fun _ ->
let signed = DownloadFile (version + "net46.zip") DateTime.UtcNow |> Async.RunSynchronously
match signed with
| Success file ->
Unzip "tmpBuild" file
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.dll", packOutputPath @@ "net46\\Microsoft.NET.Sdk.Functions.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.MSBuild.dll", buildTaskOutputPath @@ "net46\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.Generator.exe", generatorOutputPath @@ "net461\\Microsoft.NET.Sdk.Functions.Generator.exe")
| Failure e -> targetError e null |> ignore
CleanDir "tmpBuild"
let signed = DownloadFile (version + "netstandard2.zip") DateTime.UtcNow |> Async.RunSynchronously
@ -135,26 +115,18 @@ Target "WaitForSigning" (fun _ ->
| Success file ->
Unzip "tmpBuild" file
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.dll", packOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.MSBuild.dll", buildTaskOutputPath @@ "netstandard1.5\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.Generator.dll", generatorOutputPath @@ "netcoreapp2.1\\Microsoft.NET.Sdk.Functions.Generator.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.MSBuild.dll", buildTaskOutputPath @@ "netstandard2.0\\Microsoft.NET.Sdk.Functions.MSBuild.dll")
MoveFileTo ("tmpBuild" @@ "Microsoft.NET.Sdk.Functions.Generator.dll", generatorOutputPath @@ "netcoreapp3.0\\Microsoft.NET.Sdk.Functions.Generator.dll")
| Failure e -> targetError e null |> ignore
CleanDir "tmpBuild"
CleanDir "tmpBuild"
let signed = DownloadFile (version + "net46thirdparty.zip") DateTime.UtcNow |> Async.RunSynchronously
let signed = DownloadFile (version + "netstandard2thirdparty.zip") DateTime.UtcNow |> Async.RunSynchronously
match signed with
| Success file ->
Unzip "tmpBuild" file
MoveFileTo ("tmpBuild" @@ "Newtonsoft.Json.dll", generatorOutputPath @@ "net461\\Newtonsoft.Json.dll")
| Failure e -> targetError e null |> ignore
CleanDir "tmpBuild"
let signed = DownloadFile (version + "netstandard2thidparty.zip") DateTime.UtcNow |> Async.RunSynchronously
match signed with
| Success file ->
Unzip "tmpBuild" file
MoveFileTo ("tmpBuild" @@ "Newtonsoft.Json.dll", generatorOutputPath @@ "netcoreapp2.1\\Newtonsoft.Json.dll")
MoveFileTo ("tmpBuild" @@ "Newtonsoft.Json.dll", generatorOutputPath @@ "netcoreapp3.0\\Newtonsoft.Json.dll")
MoveFileTo ("tmpBuild" @@ "Mono.Cecil.dll", generatorOutputPath @@ "netcoreapp3.0\\Mono.Cecil.dll")
| Failure e -> targetError e null |> ignore
)

Просмотреть файл

@ -4,7 +4,7 @@
<Import Project="..\..\src\Microsoft.NET.Sdk.Functions.MSBuild\Targets\Microsoft.NET.Sdk.Functions.Version.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<PackageName>Microsoft.NET.Sdk.Functions</PackageName>
<Version>$(FunctionsSdkVersion)</Version>
<Authors>Microsoft</Authors>
@ -41,74 +41,41 @@
</ItemGroup>
<ItemGroup>
<!-- MSBuild task assemblies -->
<None Include="$(FunctionsBuildTaskOutputPath)\net46\Microsoft.NET.Sdk.Functions.MSBuild.dll">
<!-- MSBuild task assemblies -->
<None Include="$(FunctionsBuildTaskOutputPath)\netstandard2.0\Microsoft.NET.Sdk.Functions.MSBuild.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
</None>
<None Include="$(FunctionsBuildTaskOutputPath)\netstandard1.5\Microsoft.NET.Sdk.Functions.MSBuild.dll">
<Pack>true</Pack>
<PackagePath>tools\netcoreapp2.1\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
<!-- Generator and dependent assemblies-->
<None Include="$(FunctionsBuildTaskOutputPath)\net46\System.Net.Http.dll">
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp3.0\Newtonsoft.Json.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\net461\Newtonsoft.Json.dll">
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp3.0\Mono.Cecil.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\net461\System.ValueTuple.dll">
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp3.0\Microsoft.NET.Sdk.Functions.Generator.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\net461\Microsoft.NET.Sdk.Functions.Generator.exe">
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp3.0\Microsoft.NET.Sdk.Functions.Generator.runtimeconfig.json">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\net461\netstandard.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
</None>
<None Include="$(OutputPath)\net46\Microsoft.NET.Sdk.Functions.dll">
<Pack>true</Pack>
<PackagePath>tools\net46\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp2.1\Newtonsoft.Json.dll">
<Pack>true</Pack>
<PackagePath>tools\netcoreapp2.1\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp2.1\Microsoft.NET.Sdk.Functions.Generator.dll">
<Pack>true</Pack>
<PackagePath>tools\netcoreapp2.1\</PackagePath>
</None>
<None Include="$(FunctionsGeneratorOutputPath)\netcoreapp2.1\Microsoft.NET.Sdk.Functions.Generator.runtimeconfig.json">
<Pack>true</Pack>
<PackagePath>tools\netcoreapp2.1\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
<None Include="$(OutputPath)\netstandard2.0\Microsoft.NET.Sdk.Functions.dll">
<Pack>true</Pack>
<PackagePath>tools\netcoreapp2.1\</PackagePath>
<PackagePath>tools\netcoreapp3.0\</PackagePath>
</None>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="[3.0.0,3.1.0)" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="[3.0.0,3.1.0)" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="[3.0.0,3.1.0)" />
<PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="$(ExtensionsMetadataGeneratorVersion)" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net46'">
<PackageReference Include="Newtonsoft.Json" Version="[9.0.1]" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="[2.3.0,2.4.0)" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="[2.3.0,2.4.0)" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="[1.2.0,1.3.0)" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
</ItemGroup>
</ItemGroup>
</Project>

Просмотреть файл

@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.NET.Sdk.Functions.MakeFunction;
using Mono.Cecil;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace MakeFunctionJson
{
@ -15,9 +16,18 @@ namespace MakeFunctionJson
/// <param name="attribute"></param>
/// <returns></returns>
public static string ToAttributeFriendlyName(this Attribute attribute)
{
return ToAttributeFriendlyName(attribute.GetType().Name);
}
public static string ToAttributeFriendlyName(this CustomAttribute attribute)
{
return ToAttributeFriendlyName(attribute.AttributeType.Name);
}
private static string ToAttributeFriendlyName(string name)
{
const string suffix = nameof(Attribute);
var name = attribute.GetType().Name;
name = name.Substring(0, name.Length - suffix.Length);
return name.ToLowerFirstCharacter();
}
@ -37,15 +47,10 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="attribute"></param>
/// <returns></returns>
public static bool IsWebJobsAttribute(this Attribute attribute)
public static bool IsWebJobsAttribute(this CustomAttribute attribute)
{
#if NET46
return attribute.GetType().GetCustomAttributes().Any(a => a.GetType().FullName == "Microsoft.Azure.WebJobs.Description.BindingAttribute")
|| _supportedAttributes.Contains(attribute.GetType().Name);
#else
return attribute.GetType().GetTypeInfo().GetCustomAttributesData().Any(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.Description.BindingAttribute")
|| _supportedAttributes.Contains(attribute.GetType().Name);
#endif
return attribute.AttributeType.Resolve().CustomAttributes.Any(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.Description.BindingAttribute")
|| _supportedAttributes.Contains(attribute.AttributeType.FullName);
}
/// <summary>
@ -211,14 +216,6 @@ namespace MakeFunctionJson
return "schedule";
}
}
else if (attributeName == "EventHubTriggerAttribute" &&
attribute.GetType().Assembly.GetName().Version.Major == 2)
{
if (propertyName == "EventHubName")
{
return "path";
}
}
else if (attributeName == "ApiHubFileTrigger")
{
if (propertyName == "ConnectionStringSetting")

Просмотреть файл

@ -1,22 +0,0 @@
using System;
using System.Linq;
using System.Reflection;
namespace Microsoft.NET.Sdk.Functions.Generator
{
public static class CustomAttributeDataExtensions
{
public static Attribute ConvertToAttribute(this CustomAttributeData data)
{
var attribute = data.Constructor.Invoke(data.ConstructorArguments.Select(arg => arg.Value).ToArray()) as Attribute;
foreach (var namedArgument in data.NamedArguments)
{
(namedArgument.MemberInfo as PropertyInfo)?.SetValue(attribute, namedArgument.TypedValue.Value, null);
(namedArgument.MemberInfo as FieldInfo)?.SetValue(attribute, namedArgument.TypedValue.Value);
}
return attribute;
}
}
}

Просмотреть файл

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
using Newtonsoft.Json;
namespace MakeFunctionJson
@ -14,7 +15,7 @@ namespace MakeFunctionJson
private bool _functionsInDependencies;
private readonly HashSet<string> _excludedFunctionNames;
private readonly ILogger _logger;
private readonly IDictionary<string, MethodInfo> _functionNamesSet;
private readonly IDictionary<string, MethodDefinition> _functionNamesSet;
private static readonly IEnumerable<string> _functionsArtifacts = new[]
{
@ -34,7 +35,7 @@ namespace MakeFunctionJson
{
throw new ArgumentNullException(nameof(logger));
}
if (string.IsNullOrEmpty(assemblyPath))
{
throw new ArgumentNullException(nameof(assemblyPath));
@ -54,7 +55,7 @@ namespace MakeFunctionJson
{
_outputPath = Path.Combine(Directory.GetCurrentDirectory(), _outputPath);
}
_functionNamesSet = new Dictionary<string, MethodInfo>(StringComparer.OrdinalIgnoreCase);
_functionNamesSet = new Dictionary<string, MethodDefinition>(StringComparer.OrdinalIgnoreCase);
}
/// <summary>
@ -111,11 +112,11 @@ namespace MakeFunctionJson
}
}
public IEnumerable<(FunctionJsonSchema schema, FileInfo outputFile)?> GenerateFunctions(IEnumerable<Type> types)
public IEnumerable<(FunctionJsonSchema schema, FileInfo outputFile)?> GenerateFunctions(IEnumerable<TypeDefinition> types)
{
foreach (var type in types)
{
foreach (var method in type.GetMethods())
foreach (var method in type.Methods)
{
if (method.HasFunctionNameAttribute())
{
@ -129,7 +130,7 @@ namespace MakeFunctionJson
var functionName = method.GetSdkFunctionName();
var artifactName = Path.Combine(functionName, "function.json");
var path = Path.Combine(_outputPath, artifactName);
var relativeAssemblyPath = PathUtility.MakeRelativePath(Path.Combine(_outputPath, "dummyFunctionName"), type.Assembly.Location);
var relativeAssemblyPath = PathUtility.MakeRelativePath(Path.Combine(_outputPath, "dummyFunctionName"), type.Module.FileName);
var functionJson = method.ToFunctionJson(relativeAssemblyPath);
if (CheckAppSettingsAndFunctionName(functionJson, method))
{
@ -144,42 +145,54 @@ namespace MakeFunctionJson
{
if (method.HasNoAutomaticTriggerAttribute() && method.HasTriggerAttribute())
{
_logger.LogWarning($"Method {method.ReflectedType?.FullName}.{method.Name} has both a 'NoAutomaticTrigger' attribute and a trigger attribute. Both can't be used together for an Azure function definition.");
_logger.LogWarning($"Method {method.DeclaringType.GetReflectionFullName()}.{method.Name} has both a 'NoAutomaticTrigger' attribute and a trigger attribute. Both can't be used together for an Azure function definition.");
}
else
{
_logger.LogWarning($"Method {method.ReflectedType?.FullName}.{method.Name} is missing a trigger attribute. Both a trigger attribute and FunctionName attribute are required for an Azure function definition.");
_logger.LogWarning($"Method {method.DeclaringType.GetReflectionFullName()}.{method.Name} is missing a trigger attribute. Both a trigger attribute and FunctionName attribute are required for an Azure function definition.");
}
}
else if (method.HasValidWebJobSdkTriggerAttribute())
{
_logger.LogWarning($"Method {method.ReflectedType?.FullName}.{method.Name} is missing the 'FunctionName' attribute. Both a trigger attribute and 'FunctionName' are required for an Azure function definition.");
_logger.LogWarning($"Method {method.DeclaringType.GetReflectionFullName()}.{method.Name} is missing the 'FunctionName' attribute. Both a trigger attribute and 'FunctionName' are required for an Azure function definition.");
}
}
}
}
}
private bool TryGenerateFunctionJsons()
{
var assembly = Assembly.LoadFrom(_assemblyPath);
var assemblyRoot = Path.GetDirectoryName(_assemblyPath);
var exportedTypes = assembly.ExportedTypes;
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(assemblyRoot);
var readerParams = new ReaderParameters
{
AssemblyResolver = resolver
};
var module = ModuleDefinition.ReadModule(_assemblyPath, readerParams);
IEnumerable<TypeDefinition> exportedTypes = module.Types;
if (_functionsInDependencies)
{
foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
foreach (var referencedAssembly in module.AssemblyReferences)
{
var tryPath = Path.Combine(assemblyRoot, $"{referencedAssembly.Name}.dll");
try
if (File.Exists(tryPath))
{
var loadedAssembly = Assembly.LoadFrom(tryPath);
exportedTypes = exportedTypes.Concat(loadedAssembly.ExportedTypes);
}
catch (Exception ex)
{
_logger.LogWarning($"Could not evaluate '{referencedAssembly.Name}' for function types. Exception message: {ex.Message}");
try
{
var loadedModule = ModuleDefinition.ReadModule(tryPath, readerParams);
exportedTypes = exportedTypes.Concat(loadedModule.Types);
}
catch (Exception ex)
{
_logger.LogWarning($"Could not evaluate '{referencedAssembly.Name}' for function types. Exception message: {ex.Message}");
}
}
}
}
@ -192,7 +205,7 @@ namespace MakeFunctionJson
return functions.All(f => f.HasValue);
}
private bool CheckAppSettingsAndFunctionName(FunctionJsonSchema functionJson, MethodInfo method)
private bool CheckAppSettingsAndFunctionName(FunctionJsonSchema functionJson, MethodDefinition method)
{
try
{

Просмотреть файл

@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
using Microsoft.NET.Sdk.Functions.Generator;
using Mono.Cecil;
using Newtonsoft.Json.Linq;
namespace MakeFunctionJson
@ -13,37 +13,37 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="method">method to check if an SDK method or not.</param>
/// <returns>true if <paramref name="method"/> is a WebJobs SDK method. False otherwise.</returns>
public static bool IsWebJobsSdkMethod(this MethodInfo method)
public static bool IsWebJobsSdkMethod(this MethodDefinition method)
{
return method.HasFunctionNameAttribute() && method.HasValidWebJobSdkTriggerAttribute();
}
public static bool HasValidWebJobSdkTriggerAttribute(this MethodInfo method)
public static bool HasValidWebJobSdkTriggerAttribute(this MethodDefinition method)
{
var hasNoAutomaticTrigger = method.HasNoAutomaticTriggerAttribute();
var hasTrigger = method.HasTriggerAttribute();
return (hasNoAutomaticTrigger || hasTrigger) && !(hasNoAutomaticTrigger && hasTrigger);
}
public static bool HasFunctionNameAttribute(this MethodInfo method)
public static bool HasFunctionNameAttribute(this MethodDefinition method)
{
return method.GetCustomAttributesData().FirstOrDefault(d => d.AttributeType.FullName == "Microsoft.Azure.WebJobs.FunctionNameAttribute") != null;
return method.CustomAttributes.FirstOrDefault(d => d.AttributeType.FullName == "Microsoft.Azure.WebJobs.FunctionNameAttribute") != null;
}
public static bool HasNoAutomaticTriggerAttribute(this MethodInfo method)
public static bool HasNoAutomaticTriggerAttribute(this MethodDefinition method)
{
return method.GetCustomAttributesData().FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.NoAutomaticTriggerAttribute") != null;
return method.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.NoAutomaticTriggerAttribute") != null;
}
public static bool HasTriggerAttribute(this MethodInfo method)
public static bool HasTriggerAttribute(this MethodDefinition method)
{
return method.GetParameters().Any(p => p.IsWebJobSdkTriggerParameter());
return method.Parameters.Any(p => p.IsWebJobSdkTriggerParameter());
}
public static JObject ManualTriggerBinding(this MethodInfo method)
public static JObject ManualTriggerBinding(this MethodDefinition method)
{
var binding = new JObject { ["type"] = "manualTrigger", ["direction"] = "in" };
var stringParameter = method.GetParameters().FirstOrDefault(p => p.ParameterType == typeof(string));
var stringParameter = method.Parameters.FirstOrDefault(p => p.ParameterType.FullName == typeof(string).FullName);
if (stringParameter != null)
{
binding["name"] = stringParameter.Name;
@ -57,13 +57,13 @@ namespace MakeFunctionJson
/// <param name="method">method to convert to a <see cref="FunctionJsonSchema"/> object. The method has to be <see cref="IsWebJobsSdkMethod(MethodInfo)"/> </param>
/// <param name="assemblyPath">This will be the value of <see cref="FunctionJsonSchema.ScriptFile"/> on the returned value.</param>
/// <returns><see cref="FunctionJsonSchema"/> object that represents the passed in <paramref name="method"/>.</returns>
public static FunctionJsonSchema ToFunctionJson(this MethodInfo method, string assemblyPath)
public static FunctionJsonSchema ToFunctionJson(this MethodDefinition method, string assemblyPath)
{
return new FunctionJsonSchema
{
// For every SDK parameter, convert it to a FunctionJson bindings.
// Every parameter can potentially contain more than 1 attribute that will be converted into a binding object.
Bindings = method.HasNoAutomaticTriggerAttribute() ? new[] { method.ManualTriggerBinding() } : method.GetParameters()
Bindings = method.HasNoAutomaticTriggerAttribute() ? new[] { method.ManualTriggerBinding() } : method.Parameters
.Where(p => p.IsWebJobSdkTriggerParameter())
.Select(p => p.ToFunctionJsonBindings())
.SelectMany(i => i)
@ -82,17 +82,17 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="method">method has to be a WebJobs SDK method. <see cref="IsWebJobsSdkMethod(MethodInfo)"/></param>
/// <returns>Function name.</returns>
public static string GetSdkFunctionName(this MethodInfo method)
public static string GetSdkFunctionName(this MethodDefinition method)
{
if (!method.IsWebJobsSdkMethod())
{
throw new ArgumentException($"{nameof(method)} has to be a WebJob SDK function");
}
var functionNameAttribute = method.GetCustomAttributesData().FirstOrDefault(a => a.AttributeType.Name == "FunctionNameAttribute")?.ConvertToAttribute();
if (functionNameAttribute != null)
string functionName = method.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "FunctionNameAttribute")?.ConstructorArguments[0].Value.ToString();
if (functionName != null)
{
return functionNameAttribute.GetType().GetProperty("Name").GetValue(functionNameAttribute).ToString();
return functionName;
}
else
{
@ -107,13 +107,16 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="method"></param>
/// <returns>a boolean true or false if the outcome is fixed, a string if the ScriptHost should interpret it</returns>
public static object GetDisabled(this MethodInfo method)
public static object GetDisabled(this MethodDefinition method)
{
var attribute = method.GetParameters().Select(p => p.GetDisabledAttribute()).Where(a => a != null).FirstOrDefault() ??
var customAttribute = method.Parameters.Select(p => p.GetDisabledAttribute()).Where(a => a != null).FirstOrDefault() ??
method.GetDisabledAttribute() ??
method.DeclaringType.GetTypeInfo().GetDisabledAttribute();
if (attribute != null)
method.DeclaringType.GetDisabledAttribute();
if (customAttribute != null)
{
var attribute = customAttribute.ToReflection();
// With a SettingName defined, just put that as string. The ScriptHost will evaluate it.
var settingName = attribute.GetValue<string>("SettingName");
if (!string.IsNullOrEmpty(settingName))
@ -141,9 +144,9 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public static Attribute GetDisabledAttribute(this MethodInfo method)
public static CustomAttribute GetDisabledAttribute(this MethodDefinition method)
{
return method.GetCustomAttributesData().FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.DisableAttribute")?.ConvertToAttribute();
return method.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.DisableAttribute");
}
/// <summary>
@ -155,7 +158,7 @@ namespace MakeFunctionJson
/// <param name="method"></param>
/// <param name="error"></param>
/// <returns></returns>
public static bool HasUnsuportedAttributes(this MethodInfo method, out string error)
public static bool HasUnsuportedAttributes(this MethodDefinition method, out string error)
{
error = string.Empty;
var disabled = method.GetDisabled();

Просмотреть файл

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.1;net461</TargetFrameworks>
<TargetFramework>netcoreapp3.0</TargetFramework>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
</PropertyGroup>
@ -14,21 +14,15 @@
<DefineConstants>$(DefineConstants);RELESE_BUILD</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="[11.0.2]" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
<PackageReference Include="Newtonsoft.Json" Version="[9.0.1]" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\pack\Microsoft.NET.Sdk.Functions\Microsoft.NET.Sdk.Functions.csproj" />
<ProjectReference Include="..\Microsoft.NET.Sdk.Functions.NETStandard\Microsoft.NET.Sdk.Functions.NETStandard.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,8 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
using Newtonsoft.Json.Linq;
using System;
namespace MakeFunctionJson
{
@ -13,10 +12,10 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="parameterInfo"></param>
/// <returns></returns>
public static bool IsWebJobSdkTriggerParameter(this ParameterInfo parameterInfo)
public static bool IsWebJobSdkTriggerParameter(this ParameterDefinition parameterInfo)
{
return parameterInfo
.GetCustomAttributes()
.CustomAttributes
.Any(a => a.IsWebJobsAttribute() && a.ToAttributeFriendlyName().IndexOf("Trigger") > -1);
}
@ -25,11 +24,10 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="parameterInfo">Has to be a WebJobSdkParameter <see cref="IsWebJobsSdkParameter(ParameterInfo)"/></param>
/// <returns></returns>
public static IEnumerable<JObject> ToFunctionJsonBindings(this ParameterInfo parameterInfo)
public static IEnumerable<JObject> ToFunctionJsonBindings(this ParameterDefinition parameterInfo)
{
return parameterInfo
.GetCustomAttributes()
.CustomAttributes
.Where(a => a.IsWebJobsAttribute()) // this has to return at least 1.
.Select(a => TypeUtility.GetResolvedAttribute(parameterInfo, a)) // For IConnectionProvider logic.
.Select(a => a.ToJObject()) // Convert the Attribute into a JObject.
@ -47,9 +45,9 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="parameterInfo"></param>
/// <returns></returns>
public static Attribute GetDisabledAttribute(this ParameterInfo parameterInfo)
public static CustomAttribute GetDisabledAttribute(this ParameterDefinition parameterInfo)
{
return parameterInfo.GetCustomAttributes().FirstOrDefault(a => a.GetType().FullName == "Microsoft.Azure.WebJobs.DisableAttribute");
return parameterInfo.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.DisableAttribute");
}
}
}

Просмотреть файл

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Loader;
using MakeFunctionJson;
namespace Microsoft.NET.Sdk.Functions.Console
@ -17,9 +19,15 @@ namespace Microsoft.NET.Sdk.Functions.Console
else
{
var assemblyPath = args[0].Trim();
var assemblyDir = Path.GetDirectoryName(assemblyPath);
var outputPath = args[1].Trim();
var functionsInDependencies = bool.Parse(args[2].Trim());
AssemblyLoadContext.Default.Resolving += (context, assemblyName) =>
{
return context.LoadFromAssemblyPath(Path.Combine(assemblyDir, assemblyName.Name + ".dll"));
};
IEnumerable<string> excludedFunctionNames = Enumerable.Empty<string>();
if (args.Length > 2)

Просмотреть файл

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
namespace MakeFunctionJson
{
@ -11,9 +12,9 @@ namespace MakeFunctionJson
return typeInfo.ImplementedInterfaces.Any(i => i.Name.Equals(interfaceName, StringComparison.OrdinalIgnoreCase));
}
public static Attribute GetDisabledAttribute(this TypeInfo type)
public static CustomAttribute GetDisabledAttribute(this TypeDefinition type)
{
return type.GetCustomAttributes().FirstOrDefault(a => a.GetType().FullName == "Microsoft.Azure.WebJobs.DisableAttribute");
return type.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "Microsoft.Azure.WebJobs.DisableAttribute");
}
}
}

Просмотреть файл

@ -1,6 +1,9 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Mono.Cecil;
namespace MakeFunctionJson
{
@ -15,7 +18,7 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="parameter">The parameter to check.</param>
/// <param name="attributeType">The attribute type to look for.</param>
private static Attribute GetHierarchicalAttributeOrNull(ParameterInfo parameter, Type attributeType)
private static CustomAttribute GetHierarchicalAttributeOrNull(ParameterDefinition parameter, Type attributeType)
{
if (parameter == null)
{
@ -28,7 +31,7 @@ namespace MakeFunctionJson
return attribute;
}
var method = parameter.Member as MethodInfo;
var method = parameter.Method as MethodDefinition;
if (method == null)
{
return null;
@ -42,7 +45,7 @@ namespace MakeFunctionJson
/// </summary>
/// <param name="method">The method to check.</param>
/// <param name="type">The attribute type to look for.</param>
private static Attribute GetHierarchicalAttributeOrNull(MethodInfo method, Type type)
private static CustomAttribute GetHierarchicalAttributeOrNull(Mono.Cecil.MethodDefinition method, Type type)
{
var attribute = method.GetCustomAttribute(type);
if (attribute != null)
@ -50,7 +53,7 @@ namespace MakeFunctionJson
return attribute;
}
attribute = method.DeclaringType.GetTypeInfo().GetCustomAttribute(type);
attribute = method.DeclaringType.GetCustomAttribute(type);
if (attribute != null)
{
return attribute;
@ -59,8 +62,10 @@ namespace MakeFunctionJson
return null;
}
internal static Attribute GetResolvedAttribute(ParameterInfo parameter, Attribute attribute)
internal static Attribute GetResolvedAttribute(ParameterDefinition parameter, CustomAttribute customAttribute)
{
Attribute attribute = customAttribute.ToReflection();
if (attribute != null &&
attribute.GetType().GetTypeInfo().IsImplementing("IConnectionProvider") &&
string.IsNullOrEmpty(attribute.GetValue<string>("Connection")))
@ -75,14 +80,14 @@ namespace MakeFunctionJson
if (connectionProviderAttribute?.GetValue<Type>("ProviderType") != null)
{
var connectionOverrideProvider = GetHierarchicalAttributeOrNull(parameter, connectionProviderAttribute.GetValue<Type>("ProviderType"));
var connectionOverrideProvider = GetHierarchicalAttributeOrNull(parameter, connectionProviderAttribute.GetValue<Type>("ProviderType"))?.ToReflection();
if (connectionOverrideProvider != null &&
connectionOverrideProvider.GetType().GetTypeInfo().IsImplementing("IConnectionProvider"))
{
var iConnectionProvider = connectionOverrideProvider.GetType().GetTypeInfo().GetInterface("IConnectionProvider");
var propertyInfo = iConnectionProvider.GetProperty("Connection");
var connectionValue = (string) propertyInfo.GetValue(attribute);
connectionValue = connectionValue
var connectionValue = (string)propertyInfo.GetValue(attribute);
connectionValue = connectionValue
?? connectionOverrideProvider.GetValue<string>("Connection")
?? connectionOverrideProvider.GetValue<string>("Account");
if (!string.IsNullOrEmpty(connectionValue))
@ -95,5 +100,70 @@ namespace MakeFunctionJson
return attribute;
}
public static Attribute ToReflection(this CustomAttribute customAttribute)
{
var attributeType = customAttribute.AttributeType.ToReflectionType();
Type[] constructorParams = customAttribute.Constructor.Parameters
.Select(p => p.ParameterType.ToReflectionType())
.ToArray();
Attribute attribute = attributeType.GetConstructor(constructorParams)
.Invoke(customAttribute.ConstructorArguments.Select(p => NormalizeArg(p)).ToArray()) as Attribute;
foreach (var namedArgument in customAttribute.Properties)
{
attributeType.GetProperty(namedArgument.Name)?.SetValue(attribute, namedArgument.Argument.Value);
attributeType.GetField(namedArgument.Name)?.SetValue(attribute, namedArgument.Argument.Value);
}
return attribute;
}
public static Type ToReflectionType(this TypeReference typeDef)
{
Type t = Type.GetType(typeDef.GetReflectionFullName());
if (t == null)
{
Assembly a = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(typeDef.Resolve().Module.FileName));
t = a.GetType(typeDef.GetReflectionFullName());
}
return t;
}
private static object NormalizeArg(CustomAttributeArgument arg)
{
if (arg.Type.IsArray)
{
var arguments = arg.Value as CustomAttributeArgument[];
Type arrayType = arg.Type.GetElementType().ToReflectionType();
var array = Array.CreateInstance(arrayType, arguments.Length);
for (int i = 0; i < array.Length; i++)
{
array.SetValue(arguments[i].Value, i);
}
return array;
}
if (arg.Value is TypeDefinition typeDef)
{
return typeDef.ToReflectionType();
}
return arg.Value;
}
public static CustomAttribute GetCustomAttribute(this Mono.Cecil.ICustomAttributeProvider provider, Type parameterType)
{
return provider.CustomAttributes.SingleOrDefault(p => p.AttributeType.FullName == parameterType.FullName);
}
public static string GetReflectionFullName(this TypeReference typeRef)
{
return typeRef.FullName.Replace("/", "+");
}
}
}

Просмотреть файл

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.5;net46</TargetFrameworks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release'">
@ -19,11 +19,6 @@
<PackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.5'">
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>

Просмотреть файл

@ -11,7 +11,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<FunctionsSdkVersion>1.0.30-beta2</FunctionsSdkVersion>
<FunctionsSdkVersion>3.0.0-preview1</FunctionsSdkVersion>
</PropertyGroup>
</Project>

Просмотреть файл

@ -12,8 +12,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_FunctionsTaskFramework Condition=" '$(MSBuildRuntimeType)' == 'Core'">netcoreapp2.1</_FunctionsTaskFramework>
<_FunctionsTaskFramework Condition=" '$(_FunctionsTaskFramework)' == ''">net46</_FunctionsTaskFramework>
<_FunctionsTaskFramework>netcoreapp3.0</_FunctionsTaskFramework>
<_FunctionsTasksDir Condition=" '$(_FunctionsTasksDir)'=='' ">$(MSBuildThisFileDirectory)..\tools\$(_FunctionsTaskFramework)\</_FunctionsTasksDir>
<_FunctionsTaskAssemblyFullPath Condition=" '$(_FunctionsTaskAssemblyFullPath)'=='' ">$(_FunctionsTasksDir)\Microsoft.NET.Sdk.Functions.MSBuild.dll</_FunctionsTaskAssemblyFullPath>
<DebugSymbols Condition="'$(DebugSymbols)' == ''">true</DebugSymbols>

Просмотреть файл

@ -22,7 +22,7 @@ namespace Microsoft.NET.Sdk.Functions.Tasks
public string OutputPath { get; set; }
private const string NETFrameworkFolder = "net46";
private const string NETStandardFolder = "netcoreapp2.1";
private const string NETStandardFolder = "netcoreapp3.0";
public bool UseNETCoreGenerator { get; set; }
@ -31,7 +31,7 @@ namespace Microsoft.NET.Sdk.Functions.Tasks
public bool GenerateHostJson { get; set; }
public ITaskItem[] UserProvidedFunctionJsonFiles { get; set; }
public bool FunctionsInDependencies { get; set; }
public override bool Execute()
@ -44,7 +44,7 @@ namespace Microsoft.NET.Sdk.Functions.Tasks
}
string taskAssemblyDirectory = Path.GetDirectoryName(typeof(GenerateFunctions).GetTypeInfo().Assembly.Location);
string baseDirectory = Path.GetDirectoryName(taskAssemblyDirectory);
string baseDirectory = Path.GetDirectoryName(taskAssemblyDirectory);
ProcessStartInfo processStartInfo = null;
#if NET46
processStartInfo = GetProcessStartInfo(baseDirectory, isCore: false);
@ -68,9 +68,9 @@ namespace Microsoft.NET.Sdk.Functions.Tasks
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
process.WaitForExit();
if (!string.IsNullOrEmpty(output))
{
if (!string.IsNullOrEmpty(output))
{
Log.LogWarning(output);
}
@ -111,7 +111,7 @@ namespace Microsoft.NET.Sdk.Functions.Tasks
RedirectStandardOutput = true,
WorkingDirectory = workingDirectory,
FileName = exePath,
Arguments = arguments
Arguments = arguments
};
}
}

Просмотреть файл

@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

Просмотреть файл

@ -1,3 +0,0 @@
This is needed because netstandard.dll will only start shipping in .NETFramework 4.7.1.
All .NETFramework versions greater than 4.6.1 (minimal version that supports netstandard2.0) until 4.7.1 will need the netstandard.dll shipped along with app.

Просмотреть файл

@ -1,9 +1,10 @@
using System;
using System.Reflection;
using FluentAssertions;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs;
using Mono.Cecil;
using Xunit;
using System.Reflection;
namespace Microsoft.NET.Sdk.Functions.Test
{
@ -53,8 +54,8 @@ namespace Microsoft.NET.Sdk.Functions.Test
[InlineData(typeof(FunctionsClass3), "Run", false)]
public void MethodsWithDisabledParametersShouldBeDisabled(Type type, string methodName, object expectedIsDisabled)
{
var method = type.GetMethod(methodName);
var funcJson = method.ToFunctionJson(string.Empty);
MethodDefinition methodDef = TestUtility.GetMethodDefinition(type, methodName);
FunctionJsonSchema funcJson = methodDef.ToFunctionJson(string.Empty);
funcJson.Disabled.Should().Be(expectedIsDisabled);
}
}

Просмотреть файл

@ -1,30 +0,0 @@
using FluentAssertions;
using FluentAssertions.Json;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs.ServiceBus;
using Xunit;
namespace Microsoft.NET.Sdk.Functions.Test
{
public class EventHubAttributeTests
{
[Fact]
public static void EventHubTriggerAttribute_ShouldHaveV1vsV2Differences()
{
var attribute = new EventHubTriggerAttribute("eventHub");
var jObject = attribute.ToJObject();
#if NET46
jObject.Should().HaveElement("path");
jObject["path"].Should().Be("eventHub");
#else
jObject.Should().HaveElement("type");
jObject["type"].Should().Be("eventHubTrigger");
jObject.Should().HaveElement("path");
jObject["path"].Should().Be("eventHub");
#endif
}
}
}

Просмотреть файл

@ -4,9 +4,8 @@ using System.Linq;
using System.Net.Http;
using FluentAssertions;
using MakeFunctionJson;
using Microsoft.Azure.EventHubs;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure.Storage.Queue;
using Xunit;
@ -18,25 +17,25 @@ namespace Microsoft.NET.Sdk.Functions.Test
{
[FunctionName("MyHttpTrigger")]
public static void Run1([HttpTrigger] HttpRequestMessage request) { }
[FunctionName("MyBlobTrigger")]
public static void Run2([BlobTrigger("blob.txt")] string blobContent) { }
[FunctionName("MyQueueTrigger")]
public static void Run3([QueueTrigger("queue")] CloudQueue queue) { }
[FunctionName("MyEventHubTrigger")]
public static void Run4([EventHubTrigger("hub")] EventData message) { }
[FunctionName("MyTimerTrigger")]
public static void Run5([TimerTrigger("00:30:00")] TimerInfo timer) { }
[FunctionName("MyServiceBusTrigger")]
public static void Run6([ServiceBusTrigger("queue")] string message) { }
[FunctionName("MyManualTrigger"), NoAutomaticTrigger]
public static void Run7(string input) { }
[FunctionName("MyManualTriggerWithoutParameters"), NoAutomaticTrigger]
public static void Run8() { }
}
@ -53,16 +52,16 @@ namespace Microsoft.NET.Sdk.Functions.Test
public void FunctionMethodsAreExported(string functionName, string type, string parameterName)
{
var logger = new RecorderLogger();
var converter = new FunctionJsonConverter(logger, ".", ".", functionsInDependencies:false);
var functions = converter.GenerateFunctions(new [] {typeof(FunctionsClass)});
var converter = new FunctionJsonConverter(logger, ".", ".", functionsInDependencies: false);
var functions = converter.GenerateFunctions(new[] { TestUtility.GetTypeDefinition(typeof(FunctionsClass)) });
var schema = functions.Single(e => Path.GetFileName(e.Value.outputFile.DirectoryName) == functionName).Value.schema;
var binding = schema.Bindings.Single();
var binding = schema.Bindings.Single();
binding.Value<string>("type").Should().Be(type);
binding.Value<string>("name").Should().Be(parameterName);
logger.Errors.Should().BeEmpty();
logger.Warnings.Should().BeEmpty();
}
public class InvalidFunctionBecauseOfMissingTrigger
{
[FunctionName("MyServiceBusTrigger")]
@ -79,7 +78,7 @@ namespace Microsoft.NET.Sdk.Functions.Test
[FunctionName("MyServiceBusTrigger"), NoAutomaticTrigger]
public static void Run([ServiceBusTrigger("queue")] string message) { }
}
[Theory]
[InlineData(typeof(InvalidFunctionBecauseOfMissingTrigger), "Method Microsoft.NET.Sdk.Functions.Test.FunctionJsonConverterTests+InvalidFunctionBecauseOfMissingTrigger.Run is missing a trigger attribute. Both a trigger attribute and FunctionName attribute are required for an Azure function definition.")]
// [InlineData(typeof(InvalidFunctionBecauseOfMissingFunctionName), "Method Microsoft.NET.Sdk.Functions.Test.FunctionJsonConverterTests+InvalidFunctionBecauseOfMissingFunctionName.Run is missing the 'FunctionName' attribute. Both a trigger attribute and 'FunctionName' are required for an Azure function definition.")]
@ -87,8 +86,8 @@ namespace Microsoft.NET.Sdk.Functions.Test
public void InvalidFunctionMethodProducesWarning(Type type, string warningMessage)
{
var logger = new RecorderLogger();
var converter = new FunctionJsonConverter(logger, ".", ".", functionsInDependencies:false);
var functions = converter.GenerateFunctions(new [] {type});
var converter = new FunctionJsonConverter(logger, ".", ".", functionsInDependencies: false);
var functions = converter.GenerateFunctions(new[] { TestUtility.GetTypeDefinition(type) });
functions.Should().BeEmpty();
logger.Errors.Should().BeEmpty();
logger.Warnings.Should().ContainSingle();

Просмотреть файл

@ -1,26 +1,32 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.ServiceBus;
using Mono.Cecil;
using Xunit;
namespace Microsoft.NET.Sdk.Functions.Test
{
public class GeneralWebJobsAttributesTests
{
private static void FakeFunction(
[QueueTrigger("a")]
[BlobTrigger("b")]
[EventHubTrigger("c")]
[ServiceBusTrigger("d")] string abcd)
{
}
public static IEnumerable<object[]> GetAttributes()
{
yield return new object[] { new QueueTriggerAttribute(string.Empty) };
yield return new object[] { new BlobTriggerAttribute(string.Empty) };
yield return new object[] { new EventHubTriggerAttribute(string.Empty) };
yield return new object[] { new ServiceBusTriggerAttribute(string.Empty) };
return TestUtility.GetCustomAttributes(typeof(GeneralWebJobsAttributesTests), "FakeFunction", "abcd")
.Select(p => new object[] { p });
}
[Theory]
[MemberData(nameof(GetAttributes))]
public void IsWebJobsAttribute(Attribute attribute)
public void IsWebJobsAttribute(CustomAttribute attribute)
{
attribute.IsWebJobsAttribute().Should().BeTrue(because: $"{attribute.GetType().FullName} is a WebJob's attribute");
}

Просмотреть файл

@ -1,12 +1,8 @@
using FluentAssertions;
using System;
using System.Reflection;
using FluentAssertions;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.NET.Sdk.Functions.Test
@ -43,7 +39,7 @@ namespace Microsoft.NET.Sdk.Functions.Test
[InlineData(typeof(FunctionsClass1), "Run6", true)]
public void HasUnsupportedAttributesWorksCorrectly(Type type, string methodName, bool expected)
{
var method = type.GetMethod(methodName);
var method = TestUtility.GetMethodDefinition(type, methodName);
var hasUnsuportedAttribute = method.HasUnsuportedAttributes(out string _);
hasUnsuportedAttribute.Should().Be(expected);
}

Просмотреть файл

@ -3,8 +3,6 @@ using FluentAssertions.Json;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using System;
using System.Linq;
using Xunit;
namespace Microsoft.NET.Sdk.Functions.Test
@ -22,18 +20,5 @@ namespace Microsoft.NET.Sdk.Functions.Test
jObject.Should().HaveElement("authLevel");
jObject["authLevel"].Should().Be("function");
}
[Fact]
public void HttpTriggerAttributeWithWebHookTypeShouldntHaveAnAuthLevel()
{
var attribute = new HttpTriggerAttribute()
{
WebHookType = "something"
};
var jObject = attribute.ToJObject();
jObject["authLevel"].Should().BeNull();
}
}
}

Просмотреть файл

@ -55,8 +55,10 @@ namespace Microsoft.NET.Sdk.Functions.Test
[InlineData(typeof(FunctionsClass4), "foobarfoobar")]
public void TestIConnectionProviderHierarchicalLogic(Type type, string expected)
{
var parameterInfo = type.GetMethod("Run").GetParameters().First();
var attribute = (Attribute) parameterInfo.GetCustomAttributes(typeof(QueueTriggerAttribute), false).First();
var method = TestUtility.GetMethodDefinition(type, "Run");
var parameterInfo = method.Parameters.First();
var attribute = parameterInfo.GetCustomAttribute(typeof(QueueTriggerAttribute));
var resolvedAttribute = TypeUtility.GetResolvedAttribute(parameterInfo, attribute);

Просмотреть файл

@ -1,270 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.3.1\build\xunit.core.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9D59910B-B90E-4BBE-BD26-C2CBF85D37E1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.NET.Sdk.Functions.Test</RootNamespace>
<AssemblyName>Microsoft.NET.Sdk.Functions.Test</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>PublicKey.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<DelaySign>true</DelaySign>
<AssemblyName>Microsoft.NET.Sdk.Functions.Test</AssemblyName>
<RootNamespace>Microsoft.NET.Sdk.Functions.Test</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll</HintPath>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.19.2.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll</HintPath>
</Reference>
<Reference Include="FluentAssertions.Json, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\..\packages\FluentAssertions.Json.4.19.0\lib\net45\FluentAssertions.Json.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.Agent.Intercept, Version=2.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.2.0.7\lib\net45\Microsoft.AI.Agent.Intercept.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.DependencyCollector, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.3.0\lib\net45\Microsoft.AI.DependencyCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.3.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.ServerTelemetryChannel, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.3.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.WindowsServer, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.2.3.0\lib\net45\Microsoft.AI.WindowsServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=2.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.2.3.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Documents.Client, Version=1.11.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.1.11.4\lib\net45\Microsoft.Azure.Documents.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.Extensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions.DocumentDB, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.DocumentDB.1.0.0\lib\net45\Microsoft.Azure.WebJobs.Extensions.DocumentDB.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions.Http, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.Http.1.0.0-beta1\lib\net45\Microsoft.Azure.WebJobs.Extensions.Http.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Host, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.ServiceBus, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.ServiceBus.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.ServiceBus.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.8.2\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.8.2\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.8.2\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.DotNet.PlatformAbstractions, Version=1.1.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.DotNet.PlatformAbstractions.1.1.2\lib\net451\Microsoft.DotNet.PlatformAbstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyModel, Version=1.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Extensions.DependencyModel.1.1.0\lib\net451\Microsoft.Extensions.DependencyModel.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ServiceBus, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.ServiceBus.3.4.5\lib\net45-full\Microsoft.ServiceBus.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ServiceBus.Messaging.EventProcessorHost, Version=0.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.ServiceBus.EventProcessorHost.2.2.10\lib\net45-full\Microsoft.ServiceBus.Messaging.EventProcessorHost.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=8.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.8.6.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="NCrontab, Version=3.2.20120.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\ncrontab.3.3.0\lib\net35\NCrontab.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NSubstitute, Version=2.0.3.0, Culture=neutral, PublicKeyToken=92dd2e9066daa5ca, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSubstitute.2.0.3\lib\net45\NSubstitute.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Console, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Globalization.Calendars, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.IO.Compression.ZipFile, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Net.Sockets, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Reflection.TypeExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reflection.TypeExtensions.4.1.0\lib\net46\System.Reflection.TypeExtensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net46\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.ServiceModel" />
<Reference Include="System.Spatial, Version=5.8.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.8.2\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.ReaderWriter, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
<PackageReference Include="FluentAssertions.Json" Version="4.19.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="3.0.6" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.10" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<Compile Include="DisableAttributeTests.cs" />
<Compile Include="EventHubAttributeTests.cs" />
<Compile Include="GeneralWebJobsAttributesTests.cs" />
<Compile Include="HasUnsupportedAttributesTests.cs" />
<Compile Include="HttpTriggerTests.cs" />
<Compile Include="IConnectionProviderTests.cs" />
<Compile Include="FunctionJsonConverterTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceBusTriggerTests.cs" />
<Compile Include="RecorderLogger.cs" />
<ProjectReference Include="..\..\src\Microsoft.NET.Sdk.Functions.Generator\Microsoft.NET.Sdk.Functions.Generator.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="PublicKey.snk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.NET.Sdk.Functions.Generator\Microsoft.NET.Sdk.Functions.Generator.csproj">
<Project>{6cede940-9f0a-4b2a-97d4-d1eeee42af35}</Project>
<Name>Microsoft.NET.Sdk.Functions.Generator</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\..\packages\xunit.analyzers.0.7.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.11.4\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.11.4\build\Microsoft.Azure.DocumentDB.targets'))" />
<Error Condition="!Exists('..\..\packages\xunit.core.2.3.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.3.1\build\xunit.core.props'))" />
<Error Condition="!Exists('..\..\packages\xunit.core.2.3.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.3.1\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props'))" />
</Target>
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.11.4\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.11.4\build\Microsoft.Azure.DocumentDB.targets')" />
<Import Project="..\..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\..\packages\xunit.core.2.3.1\build\xunit.core.targets')" />
</Project>

Просмотреть файл

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Microsoft.NET.Sdk.Functions.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Microsoft.NET.Sdk.Functions.Test")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9d59910b-b90e-4bbe-bd26-c2cbf85d37e1")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -1,24 +0,0 @@
using FluentAssertions;
using FluentAssertions.Json;
using MakeFunctionJson;
using Microsoft.Azure.WebJobs;
using Microsoft.ServiceBus.Messaging;
using Xunit;
namespace Microsoft.NET.Sdk.Functions.Test
{
public class ServiceBusTriggerTests
{
[Fact]
// https://github.com/Azure/azure-functions-vs-build-sdk/issues/1
public void ServiceBusTriggerShouldHaveStringEnumForAccessRights()
{
var attribute = new ServiceBusTriggerAttribute("queue1", AccessRights.Manage);
var jObject = attribute.ToJObject();
jObject.Should().HaveElement("accessRights");
jObject["accessRights"].Should().Be("manage");
}
}
}

Просмотреть файл

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
namespace Microsoft.NET.Sdk.Functions.Test
{
public static class TestUtility
{
public static MethodDefinition GetMethodDefinition(Type type, string methodName)
{
return GetTypeDefinition(type).Methods.SingleOrDefault(p => p.Name == methodName);
}
public static TypeDefinition GetTypeDefinition(Type type)
{
var module = ModuleDefinition.ReadModule(type.Assembly.Location);
return module.GetType(type.FullName.Replace("+", "/"));
}
public static IEnumerable<CustomAttribute> GetCustomAttributes(Type type, string methodName, string parameterName)
{
var methodDef = GetMethodDefinition(type, methodName);
var paramDef = methodDef.Parameters.SingleOrDefault(p => p.Name == parameterName);
return paramDef.CustomAttributes;
}
}
}

Просмотреть файл

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="FluentAssertions.Core" publicKeyToken="33f2691a05b67b6a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.19.2.0" newVersion="4.19.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.6.0.0" newVersion="8.6.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.WebJobs.Host" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Azure.WebJobs" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.DotNet.PlatformAbstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.2.0" newVersion="1.1.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.serviceModel>
<extensions>
<!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
<behaviorExtensions>
<add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel>
<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://[your namespace].servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[your secret]" />
</appSettings>
</configuration>

Просмотреть файл

@ -28,6 +28,7 @@
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net46" />
<package id="Microsoft.Tpl.Dataflow" version="4.5.24" targetFramework="net46" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net46" />
<package id="Mono.Cecil" version="0.11.1" targetFramework="net461" />
<package id="ncrontab" version="3.3.0" targetFramework="net46" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net46" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />