Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust DI usage to workaround Host v4 bug #361

Merged
merged 14 commits into from
Dec 3, 2021
Merged
31 changes: 31 additions & 0 deletions src/ManualTests.HostV3/HttpSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using NServiceBus;

class HttpSender
{
readonly IFunctionEndpoint functionEndpoint;

public HttpSender(IFunctionEndpoint functionEndpoint)
{
this.functionEndpoint = functionEndpoint;
}

[FunctionName("InProcessHttpSenderV3")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest request, ExecutionContext executionContext, ILogger logger)
{
logger.LogInformation("C# HTTP trigger function received a request.");

var sendOptions = new SendOptions();
sendOptions.RouteToThisEndpoint();

await functionEndpoint.Send(new TriggerMessage(), sendOptions, executionContext, logger).ConfigureAwait(false);

return new OkObjectResult($"{nameof(TriggerMessage)} sent.");
}
}
26 changes: 26 additions & 0 deletions src/ManualTests.HostV3/ManualTests.HostV3.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NServiceBus.AzureFunctions.InProcess.ServiceBus\NServiceBus.AzureFunctions.InProcess.ServiceBus.csproj" />
<ProjectReference Include="..\NServiceBus.AzureFunctions.SourceGenerator\NServiceBus.AzureFunctions.SourceGenerator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions src/ManualTests.HostV3/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using NServiceBus;

[assembly: FunctionsStartup(typeof(Startup))]
[assembly: NServiceBusTriggerFunction("InProcess-HostV3")]

public class Startup : FunctionsStartup
andreasohlund marked this conversation as resolved.
Show resolved Hide resolved
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.UseNServiceBus();
}
}
5 changes: 5 additions & 0 deletions src/ManualTests.HostV3/TriggerMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using NServiceBus;

public class TriggerMessage : IMessage
{
}
15 changes: 15 additions & 0 deletions src/ManualTests.HostV3/TriggerMessageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Threading.Tasks;
using NServiceBus;
using NServiceBus.Logging;

public class TriggerMessageHandler : IHandleMessages<TriggerMessage>
{
static readonly ILog Log = LogManager.GetLogger<TriggerMessageHandler>();

public Task Handle(TriggerMessage message, IMessageHandlerContext context)
{
Log.Warn($"Handling {nameof(TriggerMessage)} in {nameof(TriggerMessageHandler)}");

return Task.CompletedTask;
}
}
3 changes: 3 additions & 0 deletions src/ManualTests.HostV3/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version": "2.0"
}
10 changes: 10 additions & 0 deletions src/ManualTests.HostV3/local.settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",

"AzureWebJobsServiceBus": "<set your ASB connection string here>",
"CustomComponentValue": "Custom Component"
}
}
31 changes: 31 additions & 0 deletions src/ManualTests.HostV4/HttpSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using NServiceBus;

class HttpSender
{
readonly IFunctionEndpoint functionEndpoint;

public HttpSender(IFunctionEndpoint functionEndpoint)
{
this.functionEndpoint = functionEndpoint;
}

[FunctionName("InProcessHttpSenderV4")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest request, ExecutionContext executionContext, ILogger logger)
{
logger.LogInformation("C# HTTP trigger function received a request.");

var sendOptions = new SendOptions();
sendOptions.RouteToThisEndpoint();

await functionEndpoint.Send(new TriggerMessage(), sendOptions, executionContext, logger).ConfigureAwait(false);

return new OkObjectResult($"{nameof(TriggerMessage)} sent.");
}
}
26 changes: 26 additions & 0 deletions src/ManualTests.HostV4/ManualTests.HostV4.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GeneratedFiles</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.*" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NServiceBus.AzureFunctions.InProcess.ServiceBus\NServiceBus.AzureFunctions.InProcess.ServiceBus.csproj" />
<ProjectReference Include="..\NServiceBus.AzureFunctions.SourceGenerator\NServiceBus.AzureFunctions.SourceGenerator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"/>
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions src/ManualTests.HostV4/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using NServiceBus;

[assembly: FunctionsStartup(typeof(Startup))]
[assembly: NServiceBusTriggerFunction("InProcess-HostV4")]

public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.UseNServiceBus();
}
}
5 changes: 5 additions & 0 deletions src/ManualTests.HostV4/TriggerMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using NServiceBus;

public class TriggerMessage : IMessage
{
}
15 changes: 15 additions & 0 deletions src/ManualTests.HostV4/TriggerMessageHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Threading.Tasks;
using NServiceBus;
using NServiceBus.Logging;

public class TriggerMessageHandler : IHandleMessages<TriggerMessage>
{
static readonly ILog Log = LogManager.GetLogger<TriggerMessageHandler>();

public Task Handle(TriggerMessage message, IMessageHandlerContext context)
{
Log.Warn($"Handling {nameof(TriggerMessage)} in {nameof(TriggerMessageHandler)}");

return Task.CompletedTask;
}
}
3 changes: 3 additions & 0 deletions src/ManualTests.HostV4/host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"version": "2.0"
}
10 changes: 10 additions & 0 deletions src/ManualTests.HostV4/local.settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",

"AzureWebJobsServiceBus": "<set your ASB connection string here>",
"CustomComponentValue": "Custom Component"
}
}
16 changes: 14 additions & 2 deletions src/NServiceBus.AzureFunctions.InProcess.ServiceBus.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29025.244
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.AzureFunctions.InProcess.ServiceBus", "NServiceBus.AzureFunctions.InProcess.ServiceBus\NServiceBus.AzureFunctions.InProcess.ServiceBus.csproj", "{C42A99C9-8FD6-4848-8E8C-1E3DB4963F98}"
EndProject
Expand All @@ -21,6 +21,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.AzureFunctions.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceBus.AcceptanceTests", "ServiceBus.AcceptanceTests\ServiceBus.AcceptanceTests.csproj", "{259C7716-0038-493C-831F-A9193C94741C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManualTests.HostV4", "ManualTests.HostV4\ManualTests.HostV4.csproj", "{D4B26C04-CD88-4356-922F-CCF69D74F442}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManualTests.HostV3", "ManualTests.HostV3\ManualTests.HostV3.csproj", "{F65EF21B-71FF-45FB-8539-5482BD052540}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -51,6 +55,14 @@ Global
{259C7716-0038-493C-831F-A9193C94741C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{259C7716-0038-493C-831F-A9193C94741C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{259C7716-0038-493C-831F-A9193C94741C}.Release|Any CPU.Build.0 = Release|Any CPU
{D4B26C04-CD88-4356-922F-CCF69D74F442}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4B26C04-CD88-4356-922F-CCF69D74F442}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4B26C04-CD88-4356-922F-CCF69D74F442}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4B26C04-CD88-4356-922F-CCF69D74F442}.Release|Any CPU.Build.0 = Release|Any CPU
{F65EF21B-71FF-45FB-8539-5482BD052540}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F65EF21B-71FF-45FB-8539-5482BD052540}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F65EF21B-71FF-45FB-8539-5482BD052540}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F65EF21B-71FF-45FB-8539-5482BD052540}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Provides extension methods to configure a <see cref="FunctionEndpoint"/> using <see cref="IFunctionsHostBuilder"/>.
/// Provides extension methods to configure a <see cref="IFunctionEndpoint"/> using <see cref="IFunctionsHostBuilder"/>.
/// </summary>
public static partial class FunctionsHostBuilderExtensions
{
Expand Down Expand Up @@ -66,7 +66,7 @@ public static void UseNServiceBus(
}

/// <summary>
/// Configures an NServiceBus endpoint that can be injected into a function trigger as a <see cref="FunctionEndpoint"/> via dependency injection.
/// Configures an NServiceBus endpoint that can be injected into a function trigger as a <see cref="IFunctionEndpoint"/> via dependency injection.
/// </summary>
public static void UseNServiceBus(
this IFunctionsHostBuilder functionsHostBuilder,
Expand All @@ -81,38 +81,33 @@ public static void UseNServiceBus(
static void RegisterEndpointFactory(IFunctionsHostBuilder functionsHostBuilder,
ServiceBusTriggeredEndpointConfiguration serviceBusTriggeredEndpointConfiguration)
{
// Provides a function to locate the file system directory containing the binaries to be loaded and scanned.
// When using functions, assemblies are moved to a 'bin' folder within FunctionsHostBuilderContext.ApplicationRootPath.
var endpointFactory = Configure(
serviceBusTriggeredEndpointConfiguration,
var startableEndpoint = Configure(
andreasohlund marked this conversation as resolved.
Show resolved Hide resolved
serviceBusTriggeredEndpointConfiguration.AdvancedConfiguration,
functionsHostBuilder.Services,
Path.Combine(functionsHostBuilder.GetContext().ApplicationRootPath, "bin"));

// for backward compatibility
functionsHostBuilder.Services.AddSingleton(endpointFactory);
functionsHostBuilder.Services.AddSingleton<IFunctionEndpoint>(sp => sp.GetRequiredService<FunctionEndpoint>());
functionsHostBuilder.Services.AddSingleton(serviceBusTriggeredEndpointConfiguration);
functionsHostBuilder.Services.AddSingleton(startableEndpoint);
functionsHostBuilder.Services.AddSingleton<IFunctionEndpoint, InProcessFunctionEndpoint>();
}

internal static Func<IServiceProvider, FunctionEndpoint> Configure(
ServiceBusTriggeredEndpointConfiguration configuration,
internal static IStartableEndpointWithExternallyManagedContainer Configure(
EndpointConfiguration endpointConfiguration,
IServiceCollection serviceCollection,
string appDirectory = null)
{
var endpointConfiguration = configuration.AdvancedConfiguration;

var scanner = endpointConfiguration.AssemblyScanner();
if (appDirectory != null)
{
scanner.AdditionalAssemblyScanningPath = appDirectory;
}

scanner.ExcludeAssemblies(FunctionEndpoint.AssembliesToExcludeFromScanning);
scanner.ExcludeAssemblies(InProcessFunctionEndpoint.AssembliesToExcludeFromScanning);

var startableEndpoint = EndpointWithExternallyManagedContainer.Create(
return EndpointWithExternallyManagedContainer.Create(
endpointConfiguration,
serviceCollection);

return serviceProvider => new FunctionEndpoint(startableEndpoint, configuration, serviceProvider);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Core;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using ExecutionContext = Microsoft.Azure.WebJobs.ExecutionContext;

/// <summary>
/// An NServiceBus endpoint hosted in Azure Function which does not receive messages automatically but only handles
/// messages explicitly passed to it by the caller.
/// </summary>
public partial interface IFunctionEndpoint
public interface IFunctionEndpoint
{
/// <summary>
/// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline. This method will lookup the <see cref="ServiceBusTriggerAttribute.AutoComplete"/> setting to determine whether to use transactional or non-transactional processing.
/// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline.
/// </summary>
Task Process(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null, CancellationToken cancellationToken = default);
Task Process(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, bool enableCrossEntityTransactions, ILogger functionsLogger = null, CancellationToken cancellationToken = default);

/// <summary>
/// Sends the provided message.
Expand Down
Loading