Skip to content

Commit

Permalink
#18 Change syntax to allow for a MultiTenant container. (#27)
Browse files Browse the repository at this point in the history
* Deprecate UseLogger
* Example with v3
* Fix build process
* Fix documentation
  • Loading branch information
junalmeida authored Oct 14, 2022
1 parent 640bcee commit ca23a6a
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:

- uses: actions/setup-dotnet@v2
with:
dotnet-version: '6.0.x'
dotnet-version: '3.1.x'

- name: "Get Commit Date"
uses: actions/[email protected]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,23 @@ public static class ConfigurationExtensions
/// <param name="hostBuilder">An instance of <see cref="IFunctionsHostBuilder"/>.</param>
/// <param name="configurationAction">Action on a <see cref="ContainerBuilder"/> that adds component registrations to the conatiner.</param>
/// <returns>The IFunctionsHostBuilder.</returns>
public static IFunctionsHostBuilder UseAutofacServiceProviderFactory(this IFunctionsHostBuilder hostBuilder, Action<ContainerBuilder> configurationAction = null)
public static IFunctionsHostBuilder UseAutofacServiceProviderFactory(this IFunctionsHostBuilder hostBuilder, Action<ContainerBuilder> configurationAction = null) =>
UseAutofacServiceProviderFactory(hostBuilder, (builder) =>
{
configurationAction?.Invoke(builder);
var container = builder.Build();
return container;
});


/// <summary>
/// Attatch the <see cref="AutofacServiceProvider"/> to the <see cref="IFunctionsHostBuilder"/> of the current function host.
/// </summary>
/// <param name="hostBuilder">An instance of <see cref="IFunctionsHostBuilder"/>.</param>
/// <param name="configurationAction">Func on a <see cref="ContainerBuilder"/> that adds component registrations to the conatiner. You may return either a regular AutofacContainer or a MultiTenantContainer.</param>
/// <returns>The IFunctionsHostBuilder.</returns>
public static IFunctionsHostBuilder UseAutofacServiceProviderFactory(this IFunctionsHostBuilder hostBuilder, Func<ContainerBuilder, IContainer> configurationAction)
{
// Adding as a Singleton service will make sure post-registered
// services like TelemetryClient will be in the scope.
Expand All @@ -34,9 +50,6 @@ public static IFunctionsHostBuilder UseAutofacServiceProviderFactory(this IFunct
containerBuilder.Populate(hostBuilder.Services);
containerBuilder.RegisterModule<LoggerModule>();
// Call the user code to configure the container
configurationAction?.Invoke(containerBuilder);
IEnvironmentType = hostBuilder.Services.Where(s => s.ServiceType.Namespace == "Microsoft.Azure.WebJobs.Script").FirstOrDefault()?.ServiceType.Assembly.GetExportedTypes().Where(x => x.Name == "IEnvironment").FirstOrDefault();
if (IEnvironmentType != null)
{
Expand All @@ -58,7 +71,12 @@ public static IFunctionsHostBuilder UseAutofacServiceProviderFactory(this IFunct
.ExternallyOwned()
.InstancePerTriggerRequest();
var container = containerBuilder.Build();
// Call the user code to configure the container
var container = configurationAction?.Invoke(containerBuilder);
if (container == null)
throw new InvalidOperationException($"Container cannot be null. Call `builder.Build()` and return either the main container or a multi-tenant container.");
return new AutofacContainer(container);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ public static class LoggerExtensions
/// <param name="hostBuilder">An instance of <see cref="IFunctionsHostBuilder"/>.</param>
/// <param name="configure">The <see cref="ILoggingBuilder"/> configuration delegate.</param>
/// <returns>The IFunctionsHostBuilder.</returns>
[Obsolete("This may replace Azure Function host logger settings and disable telemetry. Prefer using host.json `logging` settings or `services.Configure<LoggerFilterOptions>()`.")]
public static IFunctionsHostBuilder UseLogger(this IFunctionsHostBuilder hostBuilder, Action<ILoggingBuilder, IConfiguration> configure)
{
var configuration = hostBuilder.GetContext().Configuration;

hostBuilder.Services.AddLogging((config) => configure?.Invoke(config, configuration));

return hostBuilder;
}
}
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class Startup : FunctionsStartup
builder.UseAppSettings();
}

private void ConfigureContainer(ContainerBuilder builder)
private IContainer ConfigureContainer(ContainerBuilder builder)
{
builder
.Register(activator =>
Expand Down Expand Up @@ -86,6 +86,17 @@ public class Startup : FunctionsStartup
.AsImplementedInterfaces()
.InstancePerTriggerRequest();



var appContainer = builder.Build();

// If you need a Multi-Tenant Container, use this code instead of plain appContainer;
// var multiTenant = new MultitenantContainer(tenantIdentificationStrategy, appContainer);
// return multiTenant
return appContainer;

}
}

Expand Down
6 changes: 5 additions & 1 deletion SampleAutofacFunction/Functions/Function3.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.ApplicationInsights;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using SampleAutofacFunction.Services;
Expand All @@ -11,12 +12,14 @@ public class Function3 : IDisposable
{
private readonly IService1 _service1;
private readonly ILogger _logger;
private readonly TelemetryClient telemetry;
private readonly Guid _id = Guid.NewGuid();

public Function3(IService1 service1, ILogger logger)
public Function3(IService1 service1, ILogger logger, TelemetryClient telemetry)
{
_service1 = service1;
_logger = logger;
this.telemetry = telemetry;
_logger.LogWarning($"Creating {this}");
}

Expand All @@ -31,6 +34,7 @@ public async Task Run([TimerTrigger("0 */5 * * * *", RunOnStartup = true)] Timer
await Task.Delay(2000);
Activity.Current.AddTag("Test", "Hello World");
_logger.LogInformation($"C# Timer trigger function processed.");
telemetry.TrackEvent("C# Timer trigger function processed.");
}

public override string ToString()
Expand Down
14 changes: 5 additions & 9 deletions SampleAutofacFunction/SampleAutofacFunction.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.20.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="4.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.12" />
<PackageReference Include="Autofac.Multitenant" Version="6.0.0" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.21.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage.Queues" Version="5.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Logging.ApplicationInsights" Version="3.0.33" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.1.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Autofac.Extensions.DependencyInjection.AzureFunctions\Autofac.Extensions.DependencyInjection.AzureFunctions.csproj" />
Expand Down
12 changes: 9 additions & 3 deletions SampleAutofacFunction/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class Startup : FunctionsStartup
public override void Configure(IFunctionsHostBuilder builder)
{
builder
// You can call UseLogger to change how logging is done on your app by code.
.UseLogger(ConfigureLogger)
// This is the required call in order to use autofac in your azure functions app
.UseAutofacServiceProviderFactory(ConfigureContainer);
}
Expand All @@ -34,7 +32,7 @@ public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder bu
builder.UseAppSettings(true);
}

private void ConfigureContainer(ContainerBuilder builder)
private IContainer ConfigureContainer(ContainerBuilder builder)
{
builder
.Register(activator =>
Expand Down Expand Up @@ -71,6 +69,14 @@ private void ConfigureContainer(ContainerBuilder builder)
.AsImplementedInterfaces()
.InstancePerTriggerRequest();

var appContainer = builder.Build();

// If you need a Multi-Tenant Container, use this code instead of plain appContainer;

// var multiTenant = new MultitenantContainer(tenantIdentificationStrategy, appContainer);
// return multiTenant

return appContainer;
}
}
}
12 changes: 7 additions & 5 deletions SampleAutofacFunction/local.settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
}
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",

"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"APPINSIGHTS_INSTRUMENTATIONKEY": "local-dev"
}
}

0 comments on commit ca23a6a

Please sign in to comment.