এএসপি.নেট কোরে কনফিগার সার্ভিসগুলির অভ্যন্তরে ইনস্ট্যান্স কীভাবে সমাধান করা যায়


113

স্টার্টআপে পদ্ধতি IOptions<AppSettings>থেকে কোনও উদাহরণ সমাধান করা সম্ভব ConfigureServices? সাধারণত আপনি IServiceProviderউদাহরণগুলি সূচনা করতে ব্যবহার করতে পারেন তবে আপনি যখন পরিষেবাগুলি নিবন্ধভুক্ত করছেন তখন আপনার এই পর্যায়ে নেই।

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(
        configuration.GetConfigurationSection(nameof(AppSettings)));

    // How can I resolve IOptions<AppSettings> here?
}

উত্তর:


161

আপনি এই BuildServiceProvider()পদ্ধতিতে একটি পরিষেবা সরবরাহকারী তৈরি করতে পারেন IServiceCollection:

public void ConfigureService(IServiceCollection services)
{
    // Configure the services
    services.AddTransient<IFooService, FooServiceImpl>();
    services.Configure<AppSettings>(configuration.GetSection(nameof(AppSettings)));

    // Build an intermediate service provider
    var sp = services.BuildServiceProvider();

    // Resolve the services from the service provider
    var fooService = sp.GetService<IFooService>();
    var options = sp.GetService<IOptions<AppSettings>>();
}

এর Microsoft.Extensions.DependencyInjectionজন্য আপনার প্যাকেজ দরকার ।


আপনার কেবলমাত্র কয়েকটি বিকল্প বাঁধাই করতে হবে সেই ক্ষেত্রে ConfigureServices, আপনি এই Bindপদ্ধতিটিও ব্যবহার করতে পারেন :

var appSettings = new AppSettings();
configuration.GetSection(nameof(AppSettings)).Bind(appSettings);

এই কার্যকারিতা Microsoft.Extensions.Configuration.Binderপ্যাকেজের মাধ্যমে উপলব্ধ ।


অ্যাপ্লিকেশনটির অন্য কোনও অংশে যদি আপনার এই পরিষেবাটি সমাধান করার দরকার হয় তবে কী হবে? আমি নিশ্চিত যে এটি কনফিগার সার্ভিসগুলিতে (ঠিক আছে) ঠিক হয়নি?
রে

4
@ রে তারপরে আপনি ডিফল্ট নির্ভরতা ইনজেকশন পদ্ধতি যেমন কনস্ট্রাক্টর ইঞ্জেকশন ব্যবহার করতে পারেন। এই প্রশ্নটি বিশেষত ConfigureServicesপদ্ধতির অভ্যন্তরে পরিষেবাগুলি সমাধান করার বিষয়ে ।
হেন্ক মোল্লেমা

@ পিসিদেব আপনি এমনটি করার সময় নুল পাবেন এবং তারপরে উদাহরণটি সমাধান করার চেষ্টা করবেন। আপনাকে প্রথমে পরিষেবাটি যুক্ত করতে হবে।
ইনগোবি

@ ইঙ্গো হ্যাঁ, দুঃখিত, এই মন্তব্যটি ভুল ছিল এবং মুছে ফেলা উচিত - আমি যখন মন্তব্যটি লিখেছিলাম তখন কী চলছে তা আমি সঠিকভাবে বুঝতে পারি নি। দয়া করে দেখুন উত্তর আমি আগে আমি যেহেতু আপডেট করেছি যা লিঙ্ক - আমি আরো কিছু অনুসন্ধান করেছে এবং এখন এটা আরও ভাল বুঝতে।
পিসিদেব

16
যদিও এটি ক্ষেত্রে কার্যকর হতে পারে যেখানে কোনও পরিষেবা যুক্ত করার পদ্ধতির কোনও বাস্তবায়ন কারখানা ওভারলোড না থাকে (যেমন, এখানে ), BuildServiceProviderঅ্যাপ্লিকেশন কোডে ব্যবহার করা হলে যেমন সতর্কতা সৃষ্টি করে ConfigureServicesযেমন সিঙ্গলটন পরিষেবাদিগুলির অতিরিক্ত অনুলিপি হতে পারে তৈরি এহসান মিরসাইদির উত্তর এখানে এই জাতীয় ক্ষেত্রে সবচেয়ে আদর্শ সমাধান।
নিও

76

অন্যান্য পরিষেবাদির উপর নির্ভরশীল ক্লাসগুলি ইনস্ট্যান্ট করার সর্বোত্তম উপায় হ'ল আপনাকে অ্যাডএক্স XXX ওভারলোড ব্যবহার করুন যা আপনাকে IS সার্ভিসপ্রোভাইডার সরবরাহ করে । এইভাবে আপনাকে কোনও মধ্যবর্তী পরিষেবা সরবরাহকারী ইনস্ট্যান্ট করার দরকার নেই।

নিম্নলিখিত নমুনাগুলি দেখায় যে কীভাবে আপনি এই ওভারলোডটি অ্যাডসিংটন / অ্যাড ট্রান্সিয়েন্ট পদ্ধতিতে ব্যবহার করতে পারেন ।

services.AddSingleton(serviceProvider =>
{
    var options = serviceProvider.GetService<IOptions<AppSettings>>();
    var foo = new Foo(options);
    return foo ;
});


services.AddTransient(serviceProvider =>
{
    var options = serviceProvider.GetService<IOptions<AppSettings>>();
    var bar = new Bar(options);
    return bar;
});

19
নেট কোর 3 বা ততোধিকের জন্য গৃহীত উত্তরের চেয়ে এই সমাধানটি ব্যবহার করুন!
জোশিট

11
@ জোশিত আমি এতটা নিশ্চিত নই যে এটি সমস্ত পরিস্থিতিতে গ্রহণযোগ্য উত্তরের একটি কার্যকর প্রতিস্থাপন। আইএস সার্ভিসপ্রোভাইডার যেমন অ্যাডসিংটলটন, অ্যাডস্কোপড, অ্যাডট্রান্সিয়েন্টের জন্য উপলব্ধ। তবে এমন আরও অনেক অ্যাড পদ্ধতি রয়েছে যা এই ওভারলোডটি সরবরাহ করে না, যেমন অ্যাডকর্স, অ্যাডআউটথেন্টিকেশন, অ্যাডঅ্যাটোরাইজেশন।
জেপসি

4
@ জেপসি আপনি সম্পর্কিত না হওয়া বিষয়গুলি মেশান। অ্যাডকর্স, অ্যাডঅথেনটিকেশন এবং আরও অনেকগুলি সাহায্যকারী যা নিবন্ধের নীচে কল করে বিভিন্ন অন্তর্নিহিত মিডলওয়্যারগুলি ওয়্যার করতে। অ্যাডট্রান্সিয়েন্ট, অ্যাডসিংলেটন, অ্যাডস্কোপড এই তিনটি নিবন্ধকরণ (তিনটি সাধারণত ব্যবহৃত লাইফটাইম সহ)
ফ্যাব

এটি সমস্ত ক্ষেত্রে আচ্ছাদন করে না। যে সমাধান করে তার জন্য দয়া করে আমার উত্তরটি দেখুন
ইয়ান কেম্প

11

এটি অর্জনের সবচেয়ে সহজ এবং সর্বাধিক সঠিক উপায় হ'ল এএসপি.নেট কোর এর সমস্ত সংস্করণেIConfigureOptions<TOptions> ইন্টারফেসটি বাস্তবায়ন করা । এই .NET কোর 1.0 যেহেতু হয়েছে প্রায় সময়, মনে হচ্ছে যে কয়েক মানুষ সম্পর্কে জানি এটা কিভাবে যে ঠিক কাজ ™ তোলে

উদাহরণস্বরূপ, আপনি একটি কাস্টম মডেল যাচাইকারকে যুক্ত করতে চান যা আপনার অ্যাপ্লিকেশনটির অন্যান্য পরিষেবার একটিতে নির্ভরতা রাখে। প্রাথমিকভাবে এটি অসম্ভব বলে মনে হচ্ছে - সমাধান করার কোনও উপায় নেই IMyServiceDependencyকারণ আপনার কোনও প্রবেশাধিকার নেই IServiceProvider:

public class MyModelValidatorProvider : IModelValidatorProvider
{
    public MyModelValidatorProvider(IMyServiceDependency dependency)
    {
        ...
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers(options =>
    {
        options.ModelValidatorProviders.Add(new MyModelValidatorProvider(??????));
    });
}

তবে "যাদু" IConfigureOptions<TOptions>এটিকে এত সহজ করে তুলেছে:

public class ConfigureMvcOptions : IConfigureOptions<MvcOptions>
{
    private IMyServiceDependency _dependency;

    public MyMvcOptions(IMyServiceDependency dependency)
        => _dependency = dependency;

    public void Configure(MvcOptions options)
        => options.ModelValidatorProviders.Add(new MyModelValidatorProvider(_dependency));
}

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    ...

    // or scoped, or transient, as necessary for your service
    services.AddSingleton<IConfigureOptions<MvcOptions>, ConfigureMvcOptions>();
}

মূলত, আপনি যে Add***(***Options)প্রতিনিধিদের মধ্যে উপস্থাপনাগুলি করতে পারেন তা ConfigureServicesএখন আপনার IConfigureOptions<TOptions>শ্রেণীর Configureপদ্ধতিতে স্থানান্তরিত । তারপরে আপনি বিকল্পগুলি একইভাবে নিবন্ধ করুন যেভাবে আপনি অন্য কোনও পরিষেবা নিবন্ধন করতে পারেন এবং আপনি চলে যান!

আরও বিশদ জন্য, পাশাপাশি পর্দার আড়ালে এটি কীভাবে কাজ করে সে সম্পর্কিত তথ্যের জন্য আমি আপনাকে সর্বদা-অসাধারণ অ্যান্ড্রু লকের কাছে উল্লেখ করি


1

আপনি কি অনুসরণের মতো কিছু খুঁজছেন? আপনি কোডে আমার মন্তব্যগুলি একবার দেখে নিতে পারেন:

// this call would new-up `AppSettings` type
services.Configure<AppSettings>(appSettings =>
{
    // bind the newed-up type with the data from the configuration section
    ConfigurationBinder.Bind(appSettings, Configuration.GetConfigurationSection(nameof(AppSettings)));

    // modify these settings if you want to
});

// your updated app settings should be available through DI now

-1

অন্যদের যারা একই জিনিস দেখায় তাদের সহায়তা করতে চান তবে যখন অটোফ্যাকও ব্যবহার করেন।

আপনি যদি আইলাইফটাইমস্কোপ পেতে চান (যেমন বর্তমান স্কোপের ধারক) তবে আপনাকে এই app.ApplicationServices.GetAutofacRoot()পদ্ধতিতে কল করতে Configure(IApplicationBuilder app)হবে আইলাইফটাইমস্কোপ উদাহরণটি ফিরে আসবে আপনি পরিষেবাগুলি সমাধান করতে ব্যবহার করতে পারেন

public void Configure(IApplicationBuilder app)
    {
        //app middleware registrations 
        //...
        //

        ILifetimeScope autofacRoot = app.ApplicationServices.GetAutofacRoot();
        var repository = autofacRoot.Resolve<IRepository>();
    }

4
এই উত্তরটি অটোফ্যাকের কাছে খুব স্পষ্ট, যা এই প্রশ্নের ক্ষেত্রের নয়।
খাঁটি.ক্রোম

আমি অটোফ্যাক উপসর্গ দিয়ে এই প্রশ্নটি গুগল করে এখানে এসেছি এবং দুর্ভাগ্যক্রমে কোনও নির্দিষ্ট বিষয় খুঁজে পাইনি। সুতরাং আমি আশা করি যে অন্যরাও যারা এই সমস্যার সাথে লড়াই করে এই প্রশ্নে আসবেন তারা উত্তর খুঁজে পেতে পারেন।
কেবল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.