.netcore Azure functions startup class is not called - azure

My Azure function doesn't calls the startup class localy.
When running the project, my brekpoint doesn't hit the DependencyRegistrations.Register function.
Package Microsoft.Azure.Functions.Extensions is correctly installed
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
DependencyRegistrations.Register(builder.Services);
}
}
}
Why is the startup class not called?

Two things I'm not seeing in your code snippet.
1- [assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
2- Are you sure the nuget package was properly installed? (Microsoft.Azure.Functions.Extensions)
The final startup code should look like the following:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IMyService>((s) => {
return new MyService();
});
builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
}
}
}

Just in case you're running v4, Startup is not used.
Perform the dependency injection setup in Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(builder =>
{
builder.AddTransient<IUserService, UserService>();
builder.AddTransient<ICompetitionService, CompetitionService>();
builder.AddTransient<ICompetitionRepository, CompetitionRepository>();
})
.Build();
host.Run();

I face the same issue, i have to remove my project from my solution and recreate an new to have the statup to be called...
I suspect a version mistake somewhere

Related

How to inject IHttpClientFactory in Container servicestack.net?

I'm working on a solution that interacts with Redis, using the servicestack.net library.
I have a class that inherits from ServiceStack.AppHostBase and asks me for an override of the Configure method. This method has as a parameter a Funq.Container that I see is an implementation of IServiceProvider, IResolver and IContainer, and none of these interfaces have the AddHttpClient method that is provided by the IServiceCollection. Method I need to be able to inject the IHttpClientFactory. Any idea how to solve my problem?
To do it in ASP.NET (not .NET Core), the quick way would be to:
install Microsoft.Extensions.DependencyInjection package and call .AppHttpClient() extension
Build the Service Provider you would normally see in .NET Core
Get the instance of IHttpClientFactory from the Service Provider
Register the instance of IHttpClientFactory with Funq.Container again
using Microsoft.Extensions.DependencyInjection;
public class AppHost : AppHostBase
{
public override void Configure(Container container)
{
...
RegisterHttpClientFactory(container);
}
private container RegisterHttpClientFactory(Container container)
{
var services = new ServiceCollection()
.AddHttpClient();
// You can kind of inspect services returned.
// You can see this extension registers lot of other things too beside
// IHttpClientFactory.
// Also you can see the lifetime of IHttpClientFactory is Singleton.
var serviceProvider = services.BuildServiceProvider();
container.AddSingleton(serviceProvider.GetService<IHttpClientFactory>());
return container;
}
}
If you happen to use Unity Adaptor
Unity has a package to give you an extension as well to build the Service Provider directly into the Unity Container:
using Microsoft.Extensions.DependencyInjection;
using Unity;
using Unity.Microsoft.DependencyInjection;
public static class UnityConfig
{
public static void RegisterTypes(IUnityContainer container)
{
...
container.RegisterServices();
container.RegisterHttpClientFactory();
}
private static IUnityContainer RegisterHttpClientFactory(
this IUnityContainer unityContainer)
{
new ServiceCollection()
.AddHttpClient()
.BuildServiceProvider(unityContainer);
return unityContainer;
}
}
This is the interface definition of IServiceCollection from IServiceCollection.cs:
public interface IServiceCollection : IList<ServiceDescriptor>
{
}
AddHttpClient is just an extension method from Microsoft.Extensions.DependencyInjection that wraps adding a number of additional dependencies to ASP.NET Core IOC.
So you should continue to register it on ASP.NET Core IOC, i.e:
public class Startup : ModularStartup
{
public new void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseServiceStack(new AppHost
{
AppSettings = new NetCoreAppSettings(Configuration)
});
}
}
As any dependencies registered .NET Core Startup are also available to ServiceStack.

Use a stub when running Azure Functions locally

I have an Azure Functions (.NET Core) project and I would like to select an implementation for some class depending on the environment. Something like the following:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddLogging();
#if azure environment
builder.Services.AddSingleton<IAzureApi, AzureApi>();
#else
builder.Services.AddSingleton<IAzureApi, AzureApiStub>();
#endif
}
}
What would be the best way to do this? Is it possible to configure such behavior local.settings.json?
Easy way to achieve this by using custom property in the config file.
[FunctionName("CustomSettings")]
public static Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "GET")]HttpRequestMessage req, TraceWriter log)
{
var customSetting = Environment.GetEnvironmentVariable("AzureEnvironment", EnvironmentVariableTarget.Process);
if(customSetting == "Development")
{
//dosomething
}
}
Add this property in the azure portal manually (AppSettings).
for more info -> https://learn.microsoft.com/en-us/sandbox/functions-recipes/environment-variables?tabs=csharp
https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables
You could use the DEBUG preprocessor directive in your Startup.cs file:
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
#if DEBUG
builder.Services.AddSingleton<IAzureApi, AzureApiStub>();
#else
builder.Services.AddSingleton<IAzureApi, AzureApi>();
#endif
}
}
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if
You have to be running your solution in Debug configuration which I assume you would be doing when running locally?

Azure Function with EventGridTrigger prevents FunctionsStartup class's Configure method from running

I'm trying to have a function that has its dependencies injected as outlined in documentation, Use dependency injection in .NET Azure Functions. My Startup class is defined as:
using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyFunctions.Startup))]
namespace MyFunctions{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
}
}
}
I set a breakpoint on the builder.Services.AddHttpClient() statement to ensure the DI is configured.
Then I define my function using a HttpTrigger:
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace MyFunctions
{
public class ChangeProducer
{
private readonly HttpClient _httpClient;
public ChangeProducer(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
[FunctionName("ChangeProducer")]
public void Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Reservation")]HttpRequest request, ILogger log)
{
Console.WriteLine("foo");
}
}
}
When I run this from Visual Studio I hit the breakpoint in Startup.Configure. Wonderful!
Then I change my function to use an EventGridTrigger:
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
namespace MyFunctions
{
public class ChangeProducer
{
private readonly HttpClient _httpClient;
public ChangeProducer(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
[FunctionName("ChangeProducer")]
public void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
{
Console.WriteLine("foo");
}
}
}
Once that change is made, and no other change, I don't hit the breakpoint in Startup.Configure. Additionally, I know the DI is failing because when I try to invoke the function I get an error message that reads:
Executed 'ChangeProducer' (Failed, Id=06ae8b88-07c4-4150-91e5-8b88400aed72)
Microsoft.Extensions.DependencyInjection.Abstractions: Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'MyFunctions.ChangeProducer'.
Is there a known issue? I can't figure this out. The only difference is the trigger type.
Update 2019-06-24 - It's just the dependency injection
I want to be clear the issue is dependency injection isn't working, there isn't an issue with the EventGridTrigger when the dependency on HttpClient is not injected. Change the constructor to the following and the function works fine when triggered by the EventGridTrigger:
public ChangeProducer()
{
_httpClient = new HttpClient();
}
I have successfully tested with the following packages and Visual Studio 2019, version 16.1.3.
The following screen snippets show the debugging steps:
On the Start-up
Invoking a function by POST
http://localhost:7071/runtime/webhooks/EventGrid?functionName=Function1
I've figured out the dependency injection issue after creating a new function app and slowly building it out and comparing to the project that was experiencing the problem. The host.json file contained a property named extensionBundle. Once I removed that the dependency injection started working again. The entire property looks like this:
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}

How to use Sessions in ASP vNext

How can I use session variables in ASP MVC 6 ?
I couldn't find a working sample on how to store and use session variables . Can anyone help ?
add package "Microsoft.AspNet.Session": "1.0.0-beta8" to project.json and then using Microsoft.AspNet.Http;
inside that namespace you have extension methods for context.
you also need to use it with DI on Startup.cs :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSession();
}
Here's a sample controller :
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
namespace MvcWebApp.Controllers
{
[Route("[controller]")]
public class SomeController : Controller
{
public async Task<IActionResult> Edit()
{
HttpContext.Session.SetInt("myVar", 35);
}
}
}
there is a sample on the session repo on github: https://github.com/aspnet/Session/tree/release
And you can access to the session by the Controler's Session property

Determining application context from OWIN pipeline?

I have an OWIN pipeline using Nancy:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseNancy();
}
}
The UseNancy() is actually a call to my own custom extension method defined in this gist: https://gist.github.com/TheFastCat/0b7635d9e5795b44e72e
This code is executed both as an Azure Website or an Azure Cloud Service. Based on the context it is executing within I want to use a particular favicon, loaded as an embedded resource from a separate assembly. I do this by specifying separate NancyBootstrappers (each loading the proper favicon for its context).
Is there a more elegant solution to determining the runtime application that is executing the OWIN pipeline? Currently I check app.Properties["host.AppName"] ; however while the Website's app name matches it's assembly configuration, the CloudService app is the name of the Owin startup assembly.class. (see gist). It's cloogey.
Is there a more elegant/simple solution for specifying a custom favicon within Nancy for each of my web applications than creating separate bootstrappers and doing runtime application context checks?
I solved this problem with the help of others on the https://jabbr.net/#/rooms/owin and https://jabbr.net/#/rooms/nancyfx chat boards
Yes. You can contextually check the OWIN host properties:
if (app.Properties.ContainsKey("System.Net.HttpListener"))
{
// self hosted application context
}
2.) Yes.
namespace ClassLib
{
public class Startup()
{
public Startup(byte[] favIcon) { ... }
public void Configuration(IAppBuilder app) { ... }
}
}
[assembly: OwinStartup(typeof(WebHost.Startup))]
namespace WebHost
{
public class Startup()
{
public voic Configuration(IAppBuilder app)
{
new ClassLib.Startup(webhostFavIcon).Configuration(app);
}
}
}
namespace SelfHost
{
private class Program()
{
public void Main(string[] args)
{
using(WebApp.Start(app => new ClassLib.Startup(selfHostFavIcon).Configuration(app))
{}
}
}
}

Resources