c# - ASP.NET कोर DI के साथ इंस्टेंस को हल करना




dependency-injection asp.net-core (4)

आप इस तरह से AuthorizeAttribute जैसी विशेषताओं में निर्भरता को इंजेक्ट कर सकते हैं

var someservice = (ISomeService)context.HttpContext.RequestServices.GetService(typeof(ISomeService));

मैं ASP.NET कोर MVC अंतर्निहित निर्भरता इंजेक्शन ढांचे का उपयोग करके मैन्युअल रूप से एक प्रकार का समाधान कैसे करूं?

कंटेनर सेट करना काफी आसान है:

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddTransient<ISomeService, SomeConcreteService>();
}

लेकिन मैं इंजेक्शन ISomeService बिना ISomeService को कैसे हल कर सकता हूं? उदाहरण के लिए, मैं यह करना चाहता हूं:

ISomeService service = services.Resolve<ISomeService>();

IServiceCollection में ऐसी कोई विधियाँ नहीं हैं।


मैन्युअल रूप से हल करने वाले उदाहरणों में IServiceProvider इंटरफ़ेस का उपयोग करना शामिल है:

Startup.ConfigureServices में निर्भरता का समाधान

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IMyService, MyService>();

    var serviceProvider = services.BuildServiceProvider();
    var service = serviceProvider.GetService<IMyService>();
}

स्टार्टअप में निर्भरता को हल करना। कॉन्फ़िगर करें

public void Configure(
    IApplicationBuilder application,
    IServiceProvider serviceProvider)
{
    // By type.
    var service1 = (MyService)serviceProvider.GetService(typeof(MyService));

    // Using extension method.
    var service2 = serviceProvider.GetService<MyService>();

    // ...
}

रनटाइम इन्जेक्टेड सेवाओं का उपयोग करना

कुछ प्रकारों को विधि मापदंडों के रूप में इंजेक्ट किया जा सकता है:

public class Startup
{
    public Startup(
        IHostingEnvironment hostingEnvironment,
        ILoggerFactory loggerFactory)
    {
    }

    public void ConfigureServices(
        IServiceCollection services)
    {
    }

    public void Configure(
        IApplicationBuilder application,
        IHostingEnvironment hostingEnvironment,
        IServiceProvider serviceProvider,
        ILoggerFactory loggerfactory,
        IApplicationLifetime applicationLifetime)
    {
    }
}

नियंत्रक क्रियाओं में निर्भरता का समाधान

[HttpGet("/some-action")]
public string SomeAction([FromServices] IMyService myService) => "Hello";

यदि आपको इसे पंजीकृत करने के लिए किसी अन्य निर्भरता के निर्माता को पास करने के उद्देश्य से बस एक निर्भरता को हल करने की आवश्यकता है, तो आप ऐसा कर सकते हैं।

मान लें कि आपके पास एक सेवा थी जो एक स्ट्रिंग और एक ISomeService में ली गई थी।

public class AnotherService : IAnotherService
{
    public AnotherService(ISomeService someService, string serviceUrl)
    {
        ...
    }
}

जब आप इसे Startup.cs के अंदर पंजीकृत करने जाते हैं, तो आपको यह करने की आवश्यकता होगी:

services.AddScoped<IAnotherService>(ctx => 
      new AnotherService(ctx.GetService<ISomeService>(), "https://someservice.com/")
);

IServiceCollection इंटरफ़ेस का उपयोग निर्भरता इंजेक्शन कंटेनर के निर्माण के लिए किया जाता है। इसके पूर्ण रूप से निर्माण के बाद, यह एक IServiceProvider उदाहरण के लिए तैयार हो जाता है जिसका उपयोग आप सेवाओं को हल करने के लिए कर सकते हैं। आप किसी भी वर्ग में एक IServiceProvider इंजेक्षन कर सकते हैं। IApplicationBuilder और HttpContext कक्षाएं क्रमशः सेवा प्रदाता को ApplicationServices या RequestServices गुणों के माध्यम से प्रदान कर सकती हैं।

IServiceProvider एक सेवा को हल करने के लिए एक GetService(Type type) विधि को परिभाषित करता है:

var service = (IFooService)serviceProvider.GetService(typeof(IFooService));

कई सुविधा विस्तार विधियाँ भी उपलब्ध हैं, जैसे कि serviceProvider.GetService<IFooService>() ( Microsoft.Extensions.DependencyInjection serviceProvider.GetService<IFooService>() लिए एक using जोड़ें)।

स्टार्टअप क्लास के अंदर सेवाओं को हल करना

निर्भरता का इंजेक्शन लगाना

रनटाइम Startup क्लास के IHostingEnvironment जैसे IHostingEnvironment , IConfiguration और IServiceProvider में सेवाओं को इंजेक्ट कर सकता है। कृपया ध्यान दें कि यह सेवा प्रदाता होस्टिंग लेयर द्वारा निर्मित एक उदाहरण है और इसमें एप्लिकेशन शुरू करने के लिए बस सेवाएं शामिल हैं।

Configure() विधि में भी सेवाएँ इंजेक्ट की जा सकती हैं। आप IApplicationBuilder पैरामीटर के बाद मापदंडों की एक मनमानी सूची जोड़ सकते हैं। आप अपनी स्वयं की सेवाओं को भी इंजेक्ट कर सकते हैं जो यहां ConfigureServices() पद्धति में पंजीकृत हैं, वे होस्टिंग सेवा प्रदाता के बजाय एप्लिकेशन सेवा प्रदाता से हल हो जाएंगे।

public void Configure(IApplicationBuilder app, IFooService fooService)
{
   // ...
}

ConfigureServices() विधि हालांकि सेवाओं को इंजेक्ट करने की अनुमति नहीं देती है, यह केवल एक IServiceCollection तर्क को स्वीकार करती है। यह वह विधि है जहां आप अपने एप्लिकेशन निर्भरता इंजेक्शन कंटेनर को कॉन्फ़िगर करते हैं। आप यहां स्टार्टअप के कंस्ट्रक्टर में इंजेक्ट की गई सेवाओं का उपयोग कर सकते हैं। उदाहरण के लिए:

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

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
    // Use Configuration here
}

निर्भरता को मैन्युअल रूप से हल करना

यदि आप सेवाओं को मैन्युअल रूप से हल करना चाहते हैं, तो आप रनटाइम को IServiceProvider इंस्टेंस को कंस्ट्रक्टर में इंजेक्ट कर सकते हैं या IApplicationBuilder द्वारा Configure() विधि में दिए गए ApplicationServices उपयोग कर सकते हैं:

public Startup(IServiceProvider serviceProvider)
{
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}

या

public void Configure(IApplicationBuilder app)
{
    var serviceProvider = app.ApplicationServices;
    var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}

हालाँकि, यदि आपको ConfigureServices() विधि में सेवाओं को हल करने की आवश्यकता है, तो आपको एक अलग दृष्टिकोण की आवश्यकता है। आप एक IServiceCollection उदाहरण से एक मध्यवर्ती IServiceProvider निर्माण कर सकते हैं, जिसमें तब तक पंजीकृत सेवाएं शामिल हैं:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IFooService, FooService>();

    // Build the intermediate service provider
    var sp = services.BuildServiceProvider();
    var fooService = sp.GetService<IFooService>();
}

इसके लिए आपको Microsoft.Extensions.DependencyInjection dependencyInjection पैकेज की आवश्यकता है।

कृपया ध्यान दें:
आम तौर पर आपको ConfigureServices() पद्धति के अंदर सेवाओं का समाधान नहीं करना चाहिए, क्योंकि यह वास्तव में वह जगह है जहां आप एप्लिकेशन सेवाओं को कॉन्फ़िगर कर रहे हैं। कभी-कभी आपको कुछ IOptions<MyOptions> उदाहरण तक पहुंच की आवश्यकता होती है। आप इसे IConfiguration उदाहरण से IConfiguration के एक उदाहरण (जो अनिवार्य रूप से विकल्प रूपरेखा क्या है) से मानों को बांधकर पूरा कर सकते हैं:

public void ConfigureServices(IServiceCollection services)
{
    var myOptions = new MyOptions();
    Configuration.GetSection("SomeSection").Bind(myOptions);
}

सामान्य रूप से समाधान करने वाली सेवाओं (उर्फ सर्विस लोकेटर) को एक विरोधी पैटर्न के रूप में जाना जाता है । हालांकि, इसके उपयोग-मामले (चौखटे और / या बुनियादी ढांचे की परतों के लिए) हैं, आपको इसे यथासंभव अधिक से बचना चाहिए।





asp.net-core-mvc