কোনও পরিষেবা কনফিগার করার সময় নির্ভরতা ইনজেকশন সহ অ্যাজুর ফাংশন ভি 3-এ আইকনফিগুরেশন কীভাবে ইনজেক্ট বা ব্যবহার করবেন


9

সাধারণত। নেট কোর প্রকল্পে আমি ডিআই রেজিস্ট্রেশন কমান্ডের সাথে আমার পরিষেবা কনফিগার করতে একটি 'বুস্টারপ' শ্রেণি তৈরি করতাম। এটি সাধারণত IServiceCollectionআমি যেখানে কোনও পদ্ধতির মতো কল করতে পারি তার একটি এক্সটেনশন পদ্ধতি .AddCosmosDbServiceএবং প্রয়োজনীয় পদ্ধতিটি সেই পদ্ধতিটি সহ স্ট্যাটিক শ্রেণিতে 'স্ব-অন্তর্ভুক্ত'। যদিও মূল বিষয়টি হল ক্লাস IConfigurationথেকে একটি পদ্ধতি পায় Startup

আমি অতীতে অ্যাজুরে ফাংশনগুলিতে ডিআইয়ের সাথে কাজ করেছি কিন্তু এখনও এই নির্দিষ্ট প্রয়োজনীয়তাটি পূরণ করতে পারি নি।

আমি যখন কাজটি অ্যাজুরেতে স্থাপন করা হয় তখন IConfigurationআমার local.settings.jsonপাশাপাশি সেইসাথে দেব / প্রোডাকশন অ্যাপ্লিকেশন সেটিংস উভয়ের সাথে মিল রেখে সংস্থাগুলির সাথে কংক্রিটের ক্লাসে বাঁধতে ব্যবহার করছি ।

CosmosDbClientSettings.cs

/// <summary>
/// Holds configuration settings from local.settings.json or application configuration
/// </summary>    
public class CosmosDbClientSettings
{
    public string CosmosDbDatabaseName { get; set; }
    public string CosmosDbCollectionName { get; set; }
    public string CosmosDbAccount { get; set; }
    public string CosmosDbKey { get; set; }
}

BootstrapCosmosDbClient.cs

public static class BootstrapCosmosDbClient
{
    /// <summary>
    /// Adds a singleton reference for the CosmosDbService with settings obtained by injecting IConfiguration
    /// </summary>
    /// <param name="services"></param>
    /// <param name="configuration"></param>
    /// <returns></returns>
    public static async Task<CosmosDbService> AddCosmosDbServiceAsync(
        this IServiceCollection services,
        IConfiguration configuration)
    {
        CosmosDbClientSettings cosmosDbClientSettings = new CosmosDbClientSettings();
        configuration.Bind(nameof(CosmosDbClientSettings), cosmosDbClientSettings);

        CosmosClientBuilder clientBuilder = new CosmosClientBuilder(cosmosDbClientSettings.CosmosDbAccount, cosmosDbClientSettings.CosmosDbKey);
        CosmosClient client = clientBuilder.WithConnectionModeDirect().Build();
        CosmosDbService cosmosDbService = new CosmosDbService(client, cosmosDbClientSettings.CosmosDbDatabaseName, cosmosDbClientSettings.CosmosDbCollectionName);
        DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(cosmosDbClientSettings.CosmosDbDatabaseName);
        await database.Database.CreateContainerIfNotExistsAsync(cosmosDbClientSettings.CosmosDbCollectionName, "/id");

        services.AddSingleton<ICosmosDbService>(cosmosDbService);

        return cosmosDbService;
    }
}

Startup.cs

public class Startup : FunctionsStartup
{

    public override async void Configure(IFunctionsHostBuilder builder)
    {
        builder.Services.AddHttpClient();
        await builder.Services.AddCosmosDbServiceAsync(**need IConfiguration reference**); <--where do I get IConfiguration?
    }
}

একথাও ঠিক যে জন্য একটি ব্যক্তিগত ক্ষেত্র যোগ IConfigurationমধ্যে Startup.csকাজ না যেমন কিছু জনবহুল করা প্রয়োজন এবং আমি এও পড়েছি যে হবে জন্য Di ব্যবহার IConfigurationএকটি ভাল ধারণা নয়

আমি এখানে বর্ণিত বিকল্প প্যাটার্ন ব্যবহার করার চেষ্টা করেছি এবং এর মতো প্রয়োগ করেছি:

builder.Services.AddOptions<CosmosDbClientSettings>()
    .Configure<IConfiguration>((settings, configuration) => configuration.Bind(settings));

যদিও এটি IOptions<CosmosDbClientSettings>কোনও অ-স্থিত শ্রেণিতে ইনজেকশন দেওয়ার কাজ করবে , আমি আমার কনফিগারেশন কাজটি ধরে রাখতে একটি স্ট্যাটিক ক্লাস ব্যবহার করছি।

আমি কীভাবে এই কাজটি বা একটি সম্ভাব্য কাজটি করতে পারি তার কোনও পরামর্শ? আমি সমস্ত কনফিগারেশন এক জায়গায় রাখতে পছন্দ করব (বুটস্ট্র্যাপ ফাইল)।

উত্তর:


5

লিঙ্ক উদাহরণ দুর্বল ডিজাইন করা হয়েছে (আমার মতে)। এটি দৃ tight় সংযোগ এবং অ্যাসিঙ্ক-প্রতীক্ষা এবং ব্লকিং কলগুলির মিশ্রণকে উত্সাহ দেয়।

IConfigurationশুরুর অংশ হিসাবে ডিফল্টরূপে পরিষেবা সংগ্রহের সাথে যুক্ত করা হয়, তাই আমি নির্ভর করব ডিফার্ড রেজোলিউশনের সুবিধা গ্রহণের জন্য আপনার নকশাটি পরিবর্তন করার পরামর্শ দেব যাতে একটি কারখানার প্রতিনিধি ব্যবহার করে IConfigurationবিল্টের মাধ্যমে সমাধান করা যায় IServiceProvider

public static class BootstrapCosmosDbClient {

    private static event EventHandler initializeDatabase = delegate { };

    public static IServiceCollection AddCosmosDbService(this IServiceCollection services) {

        Func<IServiceProvider, ICosmosDbService> factory = (sp) => {
            //resolve configuration
            IConfiguration configuration = sp.GetService<IConfiguration>();
            //and get the configured settings (Microsoft.Extensions.Configuration.Binder.dll)
            CosmosDbClientSettings cosmosDbClientSettings = configuration.Get<CosmosDbClientSettings>();
            string databaseName = cosmosDbClientSettings.CosmosDbDatabaseName;
            string containerName = cosmosDbClientSettings.CosmosDbCollectionName;
            string account = cosmosDbClientSettings.CosmosDbAccount;
            string key = cosmosDbClientSettings.CosmosDbKey;

            CosmosClientBuilder clientBuilder = new CosmosClientBuilder(account, key);
            CosmosClient client = clientBuilder.WithConnectionModeDirect().Build();
            CosmosDbService cosmosDbService = new CosmosDbService(client, databaseName, containerName);

            //async event handler
            EventHandler handler = null;
            handler = async (sender, args) => {
                initializeDatabase -= handler; //unsubscribe
                DatabaseResponse database = await client.CreateDatabaseIfNotExistsAsync(databaseName);
                await database.Database.CreateContainerIfNotExistsAsync(containerName, "/id");
            };
            initializeDatabase += handler; //subscribe
            initializeDatabase(null, EventArgs.Empty); //raise the event to initialize db

            return cosmosDbService;
        };
        services.AddSingleton<ICosmosDbService>(factory);
        return service;
    }
}

async voidঅ-অ্যাসিঙ্ক ইভেন্ট হ্যান্ডলারে ব্যবহার করার বিষয়ে দৃষ্টিভঙ্গিটি নোট করুন ।

রেফারেন্স Async / Await - অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংয়ের সেরা অভ্যাসসমূহ

সুতরাং এখন Configureসঠিকভাবে প্রার্থনা করা যেতে পারে।

public class Startup : FunctionsStartup {

    public override void Configure(IFunctionsHostBuilder builder) =>
        builder.Services
            .AddHttpClient()
            .AddCosmosDbService();
}

4

এখানে একটি উদাহরণ রয়েছে যা আমি চাবুক মারতে সক্ষম হয়েছি; এটি কেন্দ্রীয়ীকৃত কনফিগারেশন এবং বৈশিষ্ট্য পরিচালনার জন্য অ্যাজুর অ্যাপ কনফিগারেশনের সাথে একটি সংযোগ স্থাপন করে । এক যেমন সব দ্বি বৈশিষ্ট্য ব্যবহার করতে সক্ষম হওয়া উচিত IConfigurationএবং IOptions<T>একটি ASP.NET কোর নিয়ামক মাত্র তারা would।

নিউগেট নির্ভরতা

  • Install-Package Microsoft.Azure.Functions.Extensions
  • Install-Package Microsoft.Extensions.Configuration.AzureAppConfiguration

Startup.cs

[assembly: FunctionsStartup(typeof(Startup))]

public class Startup : FunctionsStartup
{
    public override void Configure(IFunctionsHostBuilder hostBuilder) {
        var serviceProvider = hostBuilder.Services.BuildServiceProvider();
        var configurationRoot = serviceProvider.GetService<IConfiguration>();
        var configurationBuilder = new ConfigurationBuilder();
        var appConfigEndpoint = configuration["AppConfigEndpoint"];

        if (configurationRoot is IConfigurationRoot) {
            configurationBuilder.AddConfiguration(configurationRoot);
        }

        if (!string.IsNullOrEmpty(appConfigEndpoint)) {
            configurationBuilder.AddAzureAppConfiguration(appConfigOptions => {
                // possible to run this locally if refactored to use ClientSecretCredential or DefaultAzureCredential
                appConfigOptions.Connect(new Uri(appConfigEndpoint), new ManagedIdentityCredential());
            });
        }

        var configuration = configurationBuilder.Build();

        hostBuilder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), configuration));

        // Do more stuff with Configuration here...
    }
}

public sealed class HelloFunction
{
    private IConfiguration Configuration { get; }

    public HelloFunction(IConfiguration configuration) {
        Configuration = configuration;
    }

    [FunctionName("HelloFunction")]
    public void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log) {
        log.LogInformation($"Timer Trigger Fired: 'Hello {Configuration["Message"]}!'");
    }
}

এই পদ্ধতির সাথে আমার একটি সমস্যা রয়েছে যে host.jsonপ্যারামিটারগুলি বিশেষত ব্যবহার করা হয় নাroutePrefix
আন্দ্রেই

1
@ অ্যান্ড্রি আকর্ষণীয়, আমাকে কিছু গবেষণা করতে হবে এবং কোনও সমাধান পাওয়া গেলে আমার পোস্টটি সম্পাদনা করব; মাথা আপ জন্য একটি টন ধন্যবাদ!
Kittoes0124
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.