مشاركة عبر


استخدام إدخال التبعية في .NET Azure Functions

تدعم Azure Functions نمط تصميم برنامج حقن التبعية (DI)، وهو أسلوب لتحقيق عكس التحكم (IoC) بين الفئات وتبعياتها.

  • تم إنشاء إدخال التبعية في Azure Functions على ميزات .NET Core Dependency Injection. يوصى بالإلمام بحقن تبعية .NET Core . هناك اختلافات في كيفية تجاوز التبعيات وكيفية قراءة قيم التكوين باستخدام Azure Functions في خطة الاستهلاك.

  • يبدأ دعم إدخال التبعية ب Azure Functions 2.x.

  • تختلف أنماط إدخال التبعية اعتمادا على ما إذا كانت وظائف C# الخاصة بك تعمل قيد المعالجة أو خارج العملية.

هام

تنطبق الإرشادات الواردة في هذه المقالة فقط على وظائف مكتبة فئة C#‎، والتي تعمل قيد المعالجة مع وقت التشغيل. لا ينطبق نموذج إدخال التبعية المخصص هذا على وظائف .NET المعزولة، مما يتيح لك تشغيل وظائف .NET خارج العملية. يعتمد نموذج عملية العامل المعزول .NET على أنماط حقن التبعية الأساسية ASP.NET الأساسية. لمعرفة المزيد، راجع إدخال التبعية في دليل عملية العامل المعزول .NET.

المتطلبات الأساسية

قبل أن تتمكن من استخدام إدخال التبعية، يجب تثبيت حزم NuGet التالية:

تسجيل الخدمات

لتسجيل الخدمات، قم بإنشاء أسلوب لتكوين وإضافة مكونات إلى مثيل IFunctionsHostBuilder . ينشئ مضيف Azure Functions مثيلا ويمرره IFunctionsHostBuilder مباشرة إلى أسلوبك.

تحذير

بالنسبة لتطبيقات الوظائف التي تعمل في خطط Consumption أو Premium، يمكن أن تتسبب التعديلات على قيم التكوين المستخدمة في المشغلات في حدوث أخطاء في التحجيم. تؤدي أي تغييرات يتم إدخالها على هذه الخصائص FunctionsStartup بواسطة الفئة إلى حدوث خطأ في بدء تشغيل تطبيق الوظائف.

IConfiguration يمكن أن يؤدي حقن إلى سلوك غير متوقع. لمعرفة المزيد حول إضافة مصادر التكوين، راجع تخصيص مصادر التكوين.

لتسجيل الأسلوب، أضف سمة FunctionsStartup التجميع التي تحدد اسم النوع المستخدم أثناء بدء التشغيل.

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>();
    }
}

يستخدم هذا المثال حزمة Microsoft.Extensions.Http المطلوبة لتسجيل عند HttpClient بدء التشغيل.

المحاذير

يتم تشغيل سلسلة من خطوات التسجيل قبل وقت التشغيل وبعده تعالج فئة بدء التشغيل. لذلك، ضع في اعتبارك العناصر التالية:

  • فئة بدء التشغيل مخصصة للإعداد والتسجيل فقط. تجنب استخدام الخدمات المسجلة عند بدء التشغيل أثناء عملية بدء التشغيل. على سبيل المثال، لا تحاول تسجيل رسالة في مسجل يتم تسجيله أثناء بدء التشغيل. هذه النقطة من عملية التسجيل مبكرة جدا لكي تكون خدماتك متاحة للاستخدام. Configure بعد تشغيل الأسلوب، يستمر وقت تشغيل الوظائف في تسجيل تبعيات أخرى، والتي يمكن أن تؤثر على كيفية عمل خدماتك.

  • تحتوي حاوية إدخال التبعية فقط على أنواع مسجلة بشكل صريح. الخدمات الوحيدة المتوفرة لأنواع قابلة للحقن هي ما تم إعداده في Configure الأسلوب . ونتيجة لذلك، فإن الأنواع الخاصة بالوظائف مثل BindingContext و ExecutionContext غير متوفرة أثناء الإعداد أو كأنواع قابلة للحقن.

  • تكوين مصادقة ASP.NET غير مدعوم. يقوم مضيف الوظائف بتكوين خدمات المصادقة ASP.NET لعرض واجهات برمجة التطبيقات بشكل صحيح لعمليات دورة الحياة الأساسية. يمكن أن تتجاوز التكوينات الأخرى في فئة مخصصة Startup هذا التكوين، مما يؤدي إلى عواقب غير مقصودة. على سبيل المثال، يمكن أن يؤدي استدعاء builder.Services.AddAuthentication() إلى قطع المصادقة بين المدخل والمضيف، مما يؤدي إلى رسائل مثل وقت تشغيل Azure Functions غير قابل للوصول.

استخدام التبعيات التي تم إدخالها

يتم استخدام حقن الدالة الإنشائية لتوفير تبعياتك في دالة. يتطلب استخدام حقن الدالة الإنشائية عدم استخدام فئات ثابتة للخدمات المحقونة أو لفئات الدالات الخاصة بك.

يوضح النموذج التالي كيفية إدخال التبعيات IMyService و HttpClient في دالة يتم تشغيلها من قبل HTTP.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Threading.Tasks;

namespace MyNamespace;

public class MyHttpTrigger
{
    private readonly HttpClient _client;
    private readonly IMyService _service;

    public MyHttpTrigger(IHttpClientFactory httpClientFactory, IMyService service)
    {
        this._client = httpClientFactory.CreateClient();
        this._service = service;
    }

    [FunctionName("MyHttpTrigger")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        var response = await _client.GetAsync("https://microsoft.com");
        var message = _service.GetMessage();

        return new OkObjectResult("Response from function with injected dependencies.");
    }
}

يستخدم هذا المثال حزمة Microsoft.Extensions.Http المطلوبة لتسجيل عند HttpClient بدء التشغيل.

مدة بقاء الخدمة

توفر تطبيقات Azure Functions نفس عمر الخدمة مثل ASP.NET Dependency Injection. بالنسبة لتطبيق Functions، تتصرف مدة بقاء الخدمة المختلفة كما يلي:

  • عابر: يتم إنشاء الخدمات العابرة عند كل دقة للخدمة.
  • النطاق: تتطابق مدة بقاء الخدمة محددة النطاق مع مدة تنفيذ الوظيفة. يتم إنشاء الخدمات ذات النطاق مرة واحدة لكل تنفيذ وظيفة. تعيد الطلبات اللاحقة لهذه الخدمة أثناء التنفيذ إعادة استخدام مثيل الخدمة الحالي.
  • Singleton: تتطابق مدة بقاء خدمة singleton مع عمر المضيف ويتم إعادة استخدامها عبر عمليات تنفيذ الوظائف على هذا المثيل. يوصى بخدمات مدة بقاء Singleton للاتصالات والعملاء، على سبيل المثال DocumentClient أو HttpClient المثيلات.

عرض عينة من عمر الخدمة المختلفة أو تنزيلها على GitHub.

خدمات التسجيل

إذا كنت بحاجة إلى موفر التسجيل الخاص بك، فسجل نوعا مخصصا كمثيل ل ILoggerProvider، والذي يتوفر من خلال حزمة NuGet Microsoft.Extensions.Logging.Abstractions .

تتم إضافة Application Insights بواسطة Azure Functions تلقائيا.

تحذير

  • لا تقم بإضافة AddApplicationInsightsTelemetry() إلى مجموعة الخدمات، التي تسجل الخدمات التي تتعارض مع الخدمات التي تقدمها البيئة.
  • لا تقم بتسجيل الخاص بك TelemetryConfiguration أو TelemetryClient إذا كنت تستخدم وظيفة Application Insights المضمنة. إذا كنت بحاجة إلى تكوين المثيل الخاص TelemetryClient بك، فنشئ مثيلا عبر الذي تم إدخاله TelemetryConfiguration كما هو موضح في سجل بيانات تتبع الاستخدام المخصصة في وظائف C#‎.

ILogger<T> وILoggerFactory

يقوم المضيف بإدخال ILogger<T> الخدمات والخدمات ILoggerFactory في المنشئات. ومع ذلك، تتم تصفية عوامل تصفية التسجيل الجديدة هذه بشكل افتراضي من سجلات الوظائف. تحتاج إلى تعديل host.json الملف للاشتراك في عوامل تصفية وفئات إضافية.

يوضح المثال التالي كيفية إضافة ILogger<HttpTrigger> مع السجلات التي يتم عرضها للمضيف.

namespace MyNamespace;

public class HttpTrigger
{
    private readonly ILogger<HttpTrigger> _log;

    public HttpTrigger(ILogger<HttpTrigger> log)
    {
        _log = log;
    }

    [FunctionName("HttpTrigger")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
    {
        _log.LogInformation("C# HTTP trigger function processed a request.");

        // ...
}

يضيف ملف المثال host.json التالي عامل تصفية السجل.

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            }
        },
        "logLevel": {
            "MyNamespace.HttpTrigger": "Information"
        }
    }
}

لمزيد من المعلومات حول مستويات السجل، راجع تكوين مستويات السجل.

الخدمات المقدمة من تطبيق الوظائف

يسجل مضيف الدالة العديد من الخدمات. الخدمات التالية آمنة لاتخاذها تبعية في التطبيق الخاص بك:

نوع الخدمة العمر الوصف
Microsoft.Extensions.Configuration.IConfiguration المفرد تكوين وقت التشغيل
Microsoft.Azure.WebJobs.Host.Executors.IHostIdProvider المفرد مسؤول عن توفير معرف مثيل المضيف

إذا كانت هناك خدمات أخرى تريد الاعتماد عليها، فبادر بإنشاء مشكلة واقتراحها على GitHub.

تجاوز خدمات المضيف

تجاوز الخدمات التي يوفرها المضيف غير مدعوم حاليا. إذا كانت هناك خدمات تريد تجاوزها، فبادر بإنشاء مشكلة واقتراحها على GitHub.

استخدام الخيارات والإعدادات

تتوفر القيم المعرفة في إعدادات التطبيق في مثيل IConfiguration ، مما يسمح لك بقراءة قيم إعدادات التطبيق في فئة بدء التشغيل.

يمكنك استخراج القيم من المثيل IConfiguration إلى نوع مخصص. نسخ قيم إعدادات التطبيق إلى نوع مخصص يجعل من السهل اختبار خدماتك عن طريق جعل هذه القيم قابلة للحقن. يجب أن تكون الإعدادات المقروءة في مثيل التكوين أزواج مفاتيح/قيمة بسيطة. بالنسبة للوظائف التي تعمل في خطة Elastic Premium، يمكن أن تحتوي أسماء إعدادات التطبيق فقط على أحرف وأرقام (0-9) ونقاط (.) ونقاط (:) وتسطير أسفل السطر (_). لمزيد من المعلومات، راجع اعتبارات إعداد التطبيق.

خذ بعين الاعتبار الفئة التالية التي تتضمن خاصية تسمى متناسقة مع إعداد تطبيق:

public class MyOptions
{
    public string MyCustomSetting { get; set; }
}

local.settings.json وملف قد يقوم بتركيب الإعداد المخصص كما يلي:

{
  "IsEncrypted": false,
  "Values": {
    "MyOptions:MyCustomSetting": "Foobar"
  }
}

من داخل Startup.Configure الأسلوب، يمكنك استخراج القيم من المثيل IConfiguration إلى النوع المخصص باستخدام التعليمات البرمجية التالية:

builder.Services.AddOptions<MyOptions>()
    .Configure<IConfiguration>((settings, configuration) =>
    {
        configuration.GetSection("MyOptions").Bind(settings);
    });

استدعاء Bind نسخ القيم التي تحتوي على أسماء خصائص مطابقة من التكوين إلى المثيل المخصص. يتوفر مثيل الخيارات الآن في حاوية IoC لإدخالها في دالة.

يتم إدخال كائن الخيارات في الدالة كمثيل للواجهة العامة IOptions . استخدم الخاصية Value للوصول إلى القيم الموجودة في التكوين الخاص بك.

using System;
using Microsoft.Extensions.Options;

public class HttpTrigger
{
    private readonly MyOptions _settings;

    public HttpTrigger(IOptions<MyOptions> options)
    {
        _settings = options.Value;
    }
}

لمزيد من المعلومات، راجع نمط الخيارات في ASP.NET Core.

استخدام أسرار المستخدم ASP.NET Core

عند تطوير تطبيقك محليا، يوفر ASP.NET Core أداة Secret Manager تسمح لك بتخزين المعلومات السرية خارج جذر المشروع. يجعل من الأقل احتمالا أن تكون الأسرار ملتزمة عن طريق الخطأ بالتحكم في المصدر. تقرأ Azure Functions Core Tools (الإصدار 3.0.3233 أو أحدث) الأسرار التي تم إنشاؤها بواسطة ASP.NET Core Secret Manager تلقائيا.

لتكوين مشروع .NET Azure Functions لاستخدام أسرار المستخدم، قم بتشغيل الأمر التالي في جذر المشروع.

dotnet user-secrets init

ثم استخدم dotnet user-secrets set الأمر لإنشاء الأسرار أو تحديثها.

dotnet user-secrets set MySecret "my secret value"

للوصول إلى قيم أسرار المستخدم في التعليمات البرمجية لتطبيق الوظائف، استخدم IConfiguration أو IOptions.

تخصيص مصادر التكوين

لتحديد مصادر تكوين أخرى، قم بتجاوز ConfigureAppConfiguration الأسلوب في فئة تطبيق StartUp الوظائف.

يضيف النموذج التالي قيم التكوين من كل من ملفات إعدادات التطبيق الأساسية والاختيارية الخاصة بالبيئة.

using System.IO;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]

namespace MyNamespace;

public class Startup : FunctionsStartup
{
    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
        FunctionsHostBuilderContext context = builder.GetContext();

        builder.ConfigurationBuilder
            .AddJsonFile(Path.Combine(context.ApplicationRootPath, "appsettings.json"), optional: true, reloadOnChange: false)
            .AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
            .AddEnvironmentVariables();
    }
    
    public override void Configure(IFunctionsHostBuilder builder)
    {
    }
}

أضف موفري التكوين إلى ConfigurationBuilder خاصية .IFunctionsConfigurationBuilder لمزيد من المعلومات حول استخدام موفري التكوين، راجع التكوين في ASP.NET Core.

FunctionsHostBuilderContext يتم الحصول على من IFunctionsConfigurationBuilder.GetContext(). استخدم هذا السياق لاسترداد اسم البيئة الحالي وحل موقع ملفات التكوين في مجلد تطبيق الوظائف.

بشكل افتراضي، لا يتم نسخ ملفات التكوين مثل appsettings.json تلقائيا إلى مجلد إخراج تطبيق الوظائف. .csproj قم بتحديث الملف لمطابقة النموذج التالي للتأكد من نسخ الملفات.

<None Update="appsettings.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>      
</None>
<None Update="appsettings.Development.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    <CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>

الخطوات التالية

لمزيد من المعلومات، راجع الموارد التالية: