|
| 1 | + |
| 2 | +# How to Integrate Azure Functions with ASP.NET Zero |
| 3 | + |
| 4 | +**Azure Functions** is a powerful serverless computing platform that enables developers to build scalable and event-driven applications without managing infrastructure. Instead of handling server configurations manually, Azure Functions leverages the cloud to manage scaling, updates, and performance automatically—saving time and reducing costs. |
| 5 | + |
| 6 | +**ASP.NET Zero**, on the other hand, is a robust and modular application framework for building modern web applications. In some scenarios, it can be highly beneficial to integrate Azure Functions into an ASP.NET Zero-based application to handle background jobs, webhooks, or lightweight APIs efficiently. |
| 7 | + |
| 8 | +In this guide, you’ll learn how to **integrate Azure Functions with ASP.NET Zero**, step-by-step. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## Step 1: Add an Azure Functions Project to Your ASP.NET Zero Solution |
| 13 | + |
| 14 | +Start by adding a new **Azure Functions** project to your existing ASP.NET Zero solution. Since ASP.NET Zero is currently based on **.NET 9**, make sure to select the .NET 9 framework during the project setup. |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | + |
| 20 | +Once your function project is created, running it will expose an HTTP endpoint (e.g., `http://localhost:7154/api/Function1`) that returns a static message. |
| 21 | + |
| 22 | +You can test this by navigating to the displayed URL in your browser. By default, you should see the response: |
| 23 | + |
| 24 | +``` |
| 25 | +Welcome to Azure Functions! |
| 26 | +``` |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +## Step 2: Integrate ASP.NET Zero into Your Azure Function Project |
| 31 | + |
| 32 | +To integrate ASP.NET Zero functionality into your Azure Function app, you’ll need to: |
| 33 | + |
| 34 | +- Create a new **module class** |
| 35 | +- Configure **module dependencies** |
| 36 | +- Set up **dependency injection (DI)** |
| 37 | + |
| 38 | +### ✅ Create an ASP.NET Zero Module for Azure Functions |
| 39 | + |
| 40 | +ASP.NET Zero is based on **modular architecture**, so the first step is creating a module class for your Azure Function project. Here's a sample implementation: |
| 41 | + |
| 42 | +```csharp |
| 43 | +using Abp.AspNetZeroCore; |
| 44 | +using Abp.Modules; |
| 45 | +using Abp.Reflection.Extensions; |
| 46 | +using AnzAzureFunctionSample.EntityFrameworkCore; |
| 47 | +using Microsoft.Extensions.Configuration; |
| 48 | + |
| 49 | +namespace FunctionApp |
| 50 | +{ |
| 51 | + [DependsOn(typeof(AnzAzureFunctionSampleEntityFrameworkCoreModule))] |
| 52 | + public class MyFunctionModule : AbpModule |
| 53 | + { |
| 54 | + private readonly IConfigurationRoot _appConfiguration; |
| 55 | + |
| 56 | + public MyFunctionModule(AnzAzureFunctionSampleEntityFrameworkCoreModule efModule) |
| 57 | + { |
| 58 | + efModule.SkipDbSeed = true; |
| 59 | + _appConfiguration = AppConfigurations.Get( |
| 60 | + typeof(MyFunctionModule).GetAssembly().GetDirectoryPathOrNull() |
| 61 | + ); |
| 62 | + } |
| 63 | + |
| 64 | + public override void PreInitialize() |
| 65 | + { |
| 66 | + Configuration.DefaultNameOrConnectionString = _appConfiguration.GetConnectionString("Default"); |
| 67 | + Configuration.Modules.AspNetZero().LicenseCode = _appConfiguration["AbpZeroLicenseCode"]; |
| 68 | + } |
| 69 | + |
| 70 | + public override void Initialize() |
| 71 | + { |
| 72 | + IocManager.RegisterAssemblyByConvention(typeof(MyFunctionModule).GetAssembly()); |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +### 🔍 Key Points in the Module |
| 79 | + |
| 80 | +- **Module Dependency**: The module depends on `AnzAzureFunctionSampleEntityFrameworkCoreModule`. This ensures that when the function app runs, required ASP.NET Zero modules are loaded. |
| 81 | +- **Connection String**: This is required to connect to your ASP.NET Zero database. |
| 82 | +- **License Code**: ASP.NET Zero performs a license check at runtime, so this value must be set. |
| 83 | + |
| 84 | +### 📄 Add `appsettings.json` |
| 85 | + |
| 86 | +Create an `appsettings.json` file in your Azure Function project root: |
| 87 | + |
| 88 | +```json |
| 89 | +{ |
| 90 | + "ConnectionStrings": { |
| 91 | + "Default": "Server=localhost; Database={YOUR_APPS_DATABASE_NAME}; Trusted_Connection=True; TrustServerCertificate=True;" |
| 92 | + }, |
| 93 | + "AbpZeroLicenseCode": "YOUR_LICENSE_CODE", |
| 94 | + "Functions": { |
| 95 | + "Worker": { |
| 96 | + "HostEndpoint": "{URL_Of_AZURE_FUNCTION_APP}" |
| 97 | + } |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +--- |
| 103 | + |
| 104 | +## Step 3: Configure Module Dependencies for Azure Functions |
| 105 | + |
| 106 | +It’s recommended to only depend on the following modules from your ASP.NET Zero application: |
| 107 | + |
| 108 | +- **Core Module** |
| 109 | +- **EntityFrameworkCore Module** |
| 110 | + |
| 111 | +Avoid referencing `ApplicationModule` or `WebModule`, as those typically include authentication, authorization, and UI-specific logic that Azure Functions doesn't support or need. |
| 112 | + |
| 113 | +--- |
| 114 | + |
| 115 | +## Step 4: Configure Dependency Injection for ASP.NET Zero in Azure Functions |
| 116 | + |
| 117 | +To use ASP.NET Zero services (like repositories or domain services) within your Azure Functions, you must connect the **Azure Function DI system** to **ASP.NET Zero's IoC container**. |
| 118 | + |
| 119 | +Update your `Program.cs` file as shown below: |
| 120 | + |
| 121 | +```csharp |
| 122 | +using Abp; |
| 123 | +using Abp.Dependency; |
| 124 | +using Castle.Windsor.MsDependencyInjection; |
| 125 | +using FunctionApp; |
| 126 | +using Microsoft.Azure.Functions.Worker; |
| 127 | + |
| 128 | +using (var bootstrapper = AbpBootstrapper.Create<MyFunctionModule>()) |
| 129 | +{ |
| 130 | + bootstrapper.Initialize(); |
| 131 | +} |
| 132 | + |
| 133 | +var host = new HostBuilder() |
| 134 | + .ConfigureFunctionsWebApplication() |
| 135 | + .ConfigureServices(services => |
| 136 | + { |
| 137 | + services.AddApplicationInsightsTelemetryWorkerService(); |
| 138 | + services.ConfigureFunctionsApplicationInsights(); |
| 139 | + |
| 140 | + WindsorRegistrationHelper.CreateServiceProvider( |
| 141 | + IocManager.Instance.IocContainer, |
| 142 | + services |
| 143 | + ); |
| 144 | + }) |
| 145 | + .UseServiceProviderFactory(new MyServiceProviderFactory<MyFunctionModule>()) |
| 146 | + .Build(); |
| 147 | + |
| 148 | +host.Run(); |
| 149 | +``` |
| 150 | + |
| 151 | +### 🧠 What’s Happening Here? |
| 152 | + |
| 153 | +- `AbpBootstrapper` initializes the ASP.NET Zero module and dependencies. |
| 154 | +- `WindsorRegistrationHelper` combines Azure Functions’ services with ASP.NET Zero’s DI system. |
| 155 | +- `UseServiceProviderFactory` ensures ASP.NET Zero's IoC container is used as the default service provider for your function app. |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +## Step 5: Example Azure Function with ASP.NET Zero Repository |
| 160 | + |
| 161 | +Now you can inject services like `IRepository<T>` from ASP.NET Zero into your Azure Functions. |
| 162 | + |
| 163 | +```csharp |
| 164 | +using Abp.Dependency; |
| 165 | +using Abp.Domain.Repositories; |
| 166 | +using AnzAzureFunctionSample.Authorization.Roles; |
| 167 | +using Microsoft.AspNetCore.Http; |
| 168 | +using Microsoft.AspNetCore.Mvc; |
| 169 | +using Microsoft.Azure.Functions.Worker; |
| 170 | + |
| 171 | +namespace FunctionApp; |
| 172 | + |
| 173 | +public class WelcomeFunction : ITransientDependency |
| 174 | +{ |
| 175 | + private readonly ILogger<WelcomeFunction> _logger; |
| 176 | + private readonly IRepository<Role> _roleRepository; |
| 177 | + |
| 178 | + public WelcomeFunction(ILogger<WelcomeFunction> logger, IRepository<Role> roleRepository) |
| 179 | + { |
| 180 | + _logger = logger; |
| 181 | + _roleRepository = roleRepository; |
| 182 | + } |
| 183 | + |
| 184 | + [Function("WelcomeFunction")] |
| 185 | + public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req) |
| 186 | + { |
| 187 | + _logger.LogInformation("C# HTTP trigger function processed a request."); |
| 188 | + var sampleRole = _roleRepository.FirstOrDefault(e => e.Id == 1); |
| 189 | + return new OkObjectResult("Welcome to Azure Functions! -> " + sampleRole?.Name); |
| 190 | + } |
| 191 | +} |
| 192 | +``` |
| 193 | + |
| 194 | +### 🔍 How It Works |
| 195 | + |
| 196 | +This function retrieves a role with `Id = 1` from the ASP.NET Zero database and returns a message such as: |
| 197 | + |
| 198 | +``` |
| 199 | +Welcome to Azure Functions! -> admin |
| 200 | +``` |
| 201 | + |
| 202 | +Test this by sending a GET request to: |
| 203 | + |
| 204 | +``` |
| 205 | +http://localhost:7154/api/WelcomeFunction |
| 206 | +``` |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## Troubleshooting Tips |
| 211 | + |
| 212 | +- This setup was tested using **Visual Studio**. JetBrains Rider may not support Azure Functions as smoothly, especially during local execution. |
| 213 | +- If you encounter startup or DI issues, ensure: |
| 214 | + - Your `MyFunctionModule` is properly registered. |
| 215 | + - `appsettings.json` contains correct values. |
| 216 | + - You're referencing the correct modules (`Core` and `EntityFrameworkCore` only). |
| 217 | + |
| 218 | +--- |
| 219 | + |
| 220 | +## Conclusion |
| 221 | + |
| 222 | +Integrating **ASP.NET Zero with Azure Functions** allows you to harness the power of serverless architecture while still leveraging your existing domain and data layers. This setup is ideal for building lightweight APIs, background tasks, or webhooks that operate alongside your full-featured ASP.NET Zero web application. |
| 223 | + |
| 224 | +By following the steps in this guide, you can: |
| 225 | + |
| 226 | +- Reuse your business logic in a serverless context |
| 227 | +- Improve performance and scalability |
| 228 | +- Simplify cloud-native development using familiar tools |
0 commit comments