নির্ভরতা ইনজেকশন নির্মাতাদের উন্মাদনা এড়াতে কীভাবে?


300

আমি দেখতে পেয়েছি যে আমার নির্মাতারা এটি দেখতে শুরু করছেন:

public MyClass(Container con, SomeClass1 obj1, SomeClass2, obj2.... )

বর্ধমান পরামিতি তালিকা সহ। যেহেতু "ধারক" আমার নির্ভরতা ইনজেকশন ধারক, কেন আমি কেবল এটি করতে পারি না:

public MyClass(Container con)

প্রতিটি ক্লাসের জন্য? ডাউনসাইড কি কি? আমি যদি এটি করি তবে মনে হয় আমি কোনও গৌরবময় স্ট্যাটিক ব্যবহার করছি। আইওসি এবং নির্ভরতা ইনজেকশন পাগলামিতে আপনার চিন্তাভাবনাগুলি ভাগ করুন।


64
কেন আপনি পাত্রে পাস করছেন? আমি মনে করি আপনি
আইওসিটিকে

33
যদি আপনার কনস্ট্রাক্টররা আরও বা বেশি পরামিতিগুলির দাবি করে তবে আপনি এই ক্লাসে খুব বেশি কাজ করতে পারেন।
অস্টিন সালোনেন

38
আপনি কীভাবে কন্সট্রাক্টর ইঞ্জেকশন করেন তা নয়। আইওসি পাত্রে সম্পর্কে অবজেক্টগুলি মোটেই জানে না এবং তাও হওয়া উচিত।
ডাফাইমো

আপনি কেবল একটি খালি কনস্ট্রাক্টর তৈরি করতে পারেন, যার মধ্যে আপনি ডিআই-কে সরাসরি আপনার প্রয়োজনীয় জিনিস জিজ্ঞাসা করেন। এটি কনস্ট্রাক্টর ম্যাডনেসকে সরিয়ে ফেলবে তবে আপনি এটি নিশ্চিত করতে হবে যে আপনি ডিআই ইন্টারফেস ব্যবহার করছেন .. যদি আপনি আপনার ডিআই সিস্টেমটিকে অর্ধেক উন্নয়নের পরিবর্তে পরিবর্তন করেন। সত্যিই .. এইভাবে কেউ আর এটি করবে না, যদিও ডিআই আপনার নির্মাতাকে ইনজেকশনের জন্য এটি করে। দোহ
পাইওটর কুলা

উত্তর:


409

আপনি ঠিক বলেছেন যে আপনি যদি পরিষেবাটি লোকেটার হিসাবে ধারকটি ব্যবহার করেন তবে এটি কমবেশি গৌরবময় স্ট্যাটিক কারখানা। অনেক কারণেই আমি এটিকে একটি বিরোধী-প্যাটার্ন হিসাবে বিবেচনা করি

কনস্ট্রাক্টর ইঞ্জেকশনের একটি দুর্দান্ত সুবিধা হ'ল এটি একক দায়িত্বের নীতি লঙ্ঘনকে অত্যন্ত সুস্পষ্ট করে তোলে ।

যখন এটি ঘটে তখন ফেকাড পরিষেবাগুলিতে রিফ্যাক্টর করার সময় । সংক্ষেপে, একটি নতুন, আরও মোটা দানাযুক্ত ইন্টারফেস তৈরি করুন যা আপনার বর্তমানে প্রয়োজনীয় সূক্ষ্ম-নির্ভরশীল নির্ভরতাগুলির মধ্যে কিছু বা সমস্তটির মধ্যে মিথস্ক্রিয়াকে আড়াল করে।


8
একক ধারণায় রিফ্যাক্টরিং প্রচেষ্টা প্রমিতকরণের জন্য +1; দুর্দান্ত :)
রায়ান ইমারেল

46
সত্যি? এই পরামিতিগুলিকে অন্য শ্রেণিতে সরিয়ে দেওয়ার জন্য আপনি কেবল একটি ইন্ডিরিশন তৈরি করেছেন, তবে তারা এখনও সেখানে রয়েছে! তাদের মোকাবেলা করতে আরও জটিল।
অপরিবর্তনীয়

23
@ অপরিবর্তনীয়: অধঃপতনের ক্ষেত্রে যেখানে আমরা সমস্ত নির্ভরশীলতাগুলিকে একটি সামগ্রিক পরিষেবাতে স্থানান্তরিত করি তাতে আমি সম্মত হই যে এটি কেবলমাত্র অন্য মাত্রার দিকনির্দেশ যা কোনও উপকার বহন করে না, তাই আমার শব্দের পছন্দটি কিছুটা বন্ধ ছিল। যাইহোক, মুল বক্তব্যটি হ'ল আমরা কেবল কিছু সূক্ষ্ম-নির্ভরশীল নির্ভরতাগুলিকে একটি সামগ্রিক পরিষেবাতে স্থানান্তর করি । এটি নতুন সমষ্টিগত পরিষেবাতে এবং পিছনে নির্ভরতাগুলির জন্য উভয়ই নির্ভরতা অনুমতির সংখ্যা সীমিত করে। এটি উভয়ই মোকাবেলা করতে সহজ করে তোলে।
সিমমান

92
সর্বোত্তম মন্তব্য: "কনস্ট্রাক্টর ইঞ্জেকশনের একটি দুর্দান্ত সুবিধা হ'ল এটি একক দায়িত্বের নীতি লঙ্ঘনকে অত্যন্ত স্পষ্ট করে তোলে।"
ইগোর পপভ

2
@ ডনবক্স সেই ক্ষেত্রে আপনি পুনরাবৃত্তি বন্ধ করতে নাল অবজেক্টের প্রয়োগগুলি লিখতে পারেন। আপনার যা প্রয়োজন তা নয়, তবে মুল বক্তব্যটি হল কনস্ট্রাক্টর ইঞ্জেকশন চক্রটি প্রতিরোধ করে না - এটি কেবল এটি পরিষ্কার করে দেয় যে তারা সেখানে রয়েছে।
মার্ক সিমেন

66

আমি মনে করি না যে আপনার ক্লাস কনস্ট্রাক্টরগুলির আপনার আইওসি ধারক সময়ের জন্য একটি উল্লেখ থাকতে হবে। এটি আপনার শ্রেণি এবং ধারকগুলির মধ্যে অপ্রয়োজনীয় নির্ভরতা উপস্থাপন করে (নির্ভরযোগ্যতার ধরণ IOC এড়াতে চাইছে!)।


+1 একটি আইওসি ধারক উপর নির্ভর করে এটি হার্ড যে ধারক উপর পরে পরিবর্তন করে তোলে W / O অন্য সব ক্লাসের কোড গুচ্ছ পরিবর্তন
Tseng

1
কনস্ট্রাক্টরগুলিতে ইন্টারফেস পরামিতি না রেখে আপনি কীভাবে আইওসি প্রয়োগ করবেন? আমি কি আপনার পোস্টটি ভুল পড়ছি?
জে হান্ট

@ জে হান্ট আমি আপনার মন্তব্য বুঝতে পারি না। আমার কাছে, ইন্টারফেস পরামিতিগুলির অর্থ পরামিতিগুলি নির্ভরতাগুলির জন্য ইন্টারফেস, অর্থাত্ যদি আপনার নির্ভরতা ইনজেকশন ধারক আরম্ভ হয় MyClass myClass = new MyClass(IDependency1 interface1, IDependency2 interface2)(ইন্টারফেস প্যারামিটার)। এটি @ ডেরিভেশন পোস্টের সাথে সম্পর্কিত নয়, যা আমি ব্যাখ্যা করি যে একটি নির্ভরতা ইনজেকশন ধারকটিকে তার বস্তুগুলিতে নিজেকে ইনজেক্ট করা উচিত নয়,MyClass myClass = new MyClass(this)
জন দো

25

পরামিতিগুলিতে পাস করার অসুবিধাটি নয়। সমস্যাটি হ'ল আপনার ক্লাসটি খুব বেশি করছে এবং আরও ভেঙে ফেলা উচিত।

নির্ভরতা ইনজেকশন ক্লাসগুলি খুব বড় হওয়ার জন্য প্রাথমিক সতর্কতা হিসাবে কাজ করতে পারে, বিশেষত সমস্ত নির্ভরতার মধ্যে দিয়ে যাওয়ার ক্রমবর্ধমান ব্যথার কারণে pain


43
আমি ভুল হলে আমাকে সংশোধন করুন, তবে কোনও একসময় আপনাকে 'সমস্ত কিছু একসাথে আঠালো' করতে হবে, এবং এর জন্য আপনাকে এর জন্য কয়েকটি নির্ভরতার চেয়ে বেশি পেতে হবে। উদাহরণস্বরূপ দেখুন স্তরটিতে, টেমপ্লেট এবং সেগুলির জন্য ডেটা তৈরি করার সময় আপনাকে বিভিন্ন নির্ভরতা (যেমন 'পরিষেবাগুলি') থেকে সমস্ত ডেটা ধরে নিতে হবে এবং তারপরে এই সমস্ত ডেটা টেমপ্লেটে এবং স্ক্রিনে রেখে দিতে হবে। যদি আমার ওয়েব পৃষ্ঠায় 10 টি পৃথক 'ব্লক' তথ্য থাকে, তবে আমাকে সেই ডেটা সরবরাহ করার জন্য আমার 10 টি আলাদা ক্লাসের প্রয়োজন। সুতরাং আমার ভিউ / টেমপ্লেট শ্রেণিতে আমার 10 নির্ভরতা দরকার?
অ্যান্ড্রু

4

কন্সট্রাক্টর নির্ভর নির্ভরতা ইনজেকশন এবং আমি কীভাবে জটিল হয়ে উঠছিলাম তা সমস্ত নির্ভরতার মধ্যে পড়ার বিষয়ে একটি একই প্রশ্নে এসেছি।

আমি অতীতে যে পদ্ধতির ব্যবহার করেছি তার মধ্যে একটি হ'ল একটি পরিষেবা স্তর ব্যবহার করে অ্যাপ্লিকেশন সম্মুখের প্যাটার্নটি ব্যবহার করা। এটিতে একটি মোটা API থাকবে। যদি এই পরিষেবাটি সংগ্রহস্থলের উপর নির্ভর করে তবে এটি ব্যক্তিগত সম্পত্তিগুলির একটি সেটার ইঞ্জেকশন ব্যবহার করবে। এর জন্য একটি বিমূর্ত কারখানা তৈরি করা উচিত এবং সংগ্রহশালা তৈরির যুক্তি কারখানায় সরিয়ে নেওয়া দরকার।

ব্যাখ্যা সহ বিশদ কোডটি এখানে পাওয়া যাবে

জটিল পরিষেবা স্তরে আইওসির জন্য সেরা অনুশীলন


3

আমি এই পুরো থ্রেডটি দু'বার পড়েছি এবং আমি মনে করি যে লোকেরা যা জানতে চায় তার দ্বারা প্রতিক্রিয়া জানায়, যা জিজ্ঞাসিত তা দ্বারা নয়।

জেপির আসল প্রশ্নটি দেখে মনে হচ্ছে যে তিনি একটি রেজলভার এবং তারপরে ক্লাসগুলির একগুচ্ছ পাঠিয়ে অবজেক্টগুলি তৈরি করছেন, তবে আমরা ধরে নিচ্ছি যে classes শ্রেণিগুলি / অবজেক্টগুলি নিজেরাই সার্ভিস, ইনজেকশনের জন্য পাকা। তারা না থাকলে কী হবে?

জেপি, আপনি যদি ডিআই-কে উপার্জনের সন্ধান করছেন এবং প্রাসঙ্গিক তথ্যগুলির সাথে ইঞ্জেকশন মিশ্রণের গৌরব অর্জন করতে চান তবে এই নিদর্শনগুলির মধ্যে কোনওটিই (বা অনুমিত "অ্যান্টি-প্যাটার্ন") নির্দিষ্টভাবে এটিকে সম্বোধন করে না। এটি আসলে এমন একটি প্যাকেজ ব্যবহার করতে শুরু করে যা আপনাকে এইরকম প্রচেষ্টাতে সমর্থন করবে।

Container.GetSevice<MyClass>(someObject1, someObject2)

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

তবে এটি করা উচিত, কারণ আমার মাই ক্লাস'এর জন্য একটি কারখানা তৈরি করতে এবং নিবন্ধিত করতে সক্ষম হওয়া উচিত, এবং সেই কারখানার এমন ডেটা / ইনপুট গ্রহণ করা উচিত যা কেবল পাস করার জন্য "পরিষেবা" হয়ে যায় না ডেটা। যদি "অ্যান্টি-প্যাটার্ন" নেতিবাচক পরিণতি সম্পর্কে হয়, তবে ডেটা / মডেলগুলি পাস করার জন্য কৃত্রিম পরিষেবা ধরণের অস্তিত্বকে বাধ্য করা অবশ্যই নেতিবাচক (আপনার ক্লাসগুলি একটি ধারক মধ্যে গুটিয়ে রাখা সম্পর্কে আপনার অনুভূতির সাথে সমান। একই প্রবৃত্তি প্রযোজ্য)।

কিছু কাঠামো দেখানো হলেও এমন কাঠামো রয়েছে যা সহায়তা করতে পারে। উদাহরণস্বরূপ, নিনজেক্ট:

কনস্ট্রাক্টরের অতিরিক্ত পরামিতি সহ নিনজেক্ট ব্যবহার করে একটি উদাহরণ তৈরি করা

এটি নেট জন্য, জনপ্রিয়, এবং এখনও এটি যতটা পরিষ্কার হওয়া উচিত তেমন নেই, তবে আমি নিশ্চিত যে আপনি নিয়োগের জন্য যে কোনও ভাষা বেছে নিন something


3

ধারকটি ইনজেকশন করা একটি শর্টকাট যা আপনি শেষ পর্যন্ত অনুশোচনা করবেন।

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

এখানে সন্ধান করা জিনিসগুলির একটি অসম্পূর্ণ তালিকা

দরিদ্র ডোমেন ডিজাইন (সমষ্টিগত মূলের…। ইত্যাদি)

উদ্বেগের দুর্বল পৃথকীকরণ (পরিষেবা রচনা, কমান্ড, কোয়েরি) সিকিউআরএস এবং ইভেন্ট সোর্সিং দেখুন।

বা ম্যাপার্স (সাবধান হন, এই জিনিসগুলি আপনাকে সমস্যায় ফেলতে পারে)

মডেলগুলি এবং অন্যান্য ডিটিও'র দেখুন (কখনই এটির পুনরায় ব্যবহার করবেন না এবং এগুলিকে ন্যূনতম রাখার চেষ্টা করুন !!!!)


2

সমস্যা:

1) ক্রমবর্ধমান পরামিতি তালিকা সহ নির্মাণকারী।

2) শ্রেণি যদি উত্তরাধিকার সূত্রে প্রাপ্ত হয় (প্রাক্তন RepositoryBase:) তবে কনস্ট্রাক্টর স্বাক্ষর পরিবর্তনগুলি উত্পন্ন ক্লাসগুলিতে পরিবর্তন ঘটায়।

সমাধান ঘ

IoC Containerকনস্ট্রাক্টর পাস

কেন

  • আর কখনও বাড়ছে প্যারামিটার তালিকা
  • নির্মাতার স্বাক্ষর সহজ হয়ে যায়

কেন না

  • আইওসি ধারককে শক্ত করে মিলিয়ে আপনার ক্লাস করে। (এটি যখন সমস্যার সৃষ্টি করে যখন ১। আপনি অন্যান্য প্রকল্পে যেখানে ক্লাসটি ব্যবহার করতে চান যেখানে আপনি বিভিন্ন আইওসি ধারক ব্যবহার করেন 2.. আপনি আইওসি ধারক পরিবর্তন করার সিদ্ধান্ত নেন)
  • আপনাকে ক্লাস কম বর্ণনামূলক করে তোলে। (আপনি সত্যই ক্লাস কনস্ট্রাক্টরের দিকে তাকাতে পারবেন না এবং কার্যকারিতার জন্য এটি কী প্রয়োজন তা বলতে পারেন না))
  • ক্লাস সম্ভাব্য সমস্ত পরিষেবা অ্যাক্সেস করতে পারে।

সমাধান 2

একটি ক্লাস তৈরি করুন যা সমস্ত পরিষেবাকে গ্রুপ করে এবং এটি কনস্ট্রাক্টরে পাস করে

 public abstract class EFRepositoryBase 
 {
    public class Dependency
    {
        public DbContext DbContext { get; }
        public IAuditFactory AuditFactory { get; }

         public Dependency(
            DbContext dbContext,
            IAuditFactory auditFactory)
        {
            DbContext = dbContext;
            AuditFactory = auditFactory;
        }
    }

    protected readonly DbContext DbContext;        
    protected readonly IJobariaAuditFactory auditFactory;

    protected EFRepositoryBase(Dependency dependency)
    {
        DbContext = dependency.DbContext;
        auditFactory= dependency.JobariaAuditFactory;
    }
  }

উত্সর্গীকৃত ক্লাস

  public class ApplicationEfRepository : EFRepositoryBase      
  {
     public new class Dependency : EFRepositoryBase.Dependency
     {
         public IConcreteDependency ConcreteDependency { get; }

         public Dependency(
            DbContext dbContext,
            IAuditFactory auditFactory,
            IConcreteDependency concreteDependency)
        {
            DbContext = dbContext;
            AuditFactory = auditFactory;
            ConcreteDependency = concreteDependency;
        }
     }

      IConcreteDependency _concreteDependency;

      public ApplicationEfRepository(
          Dependency dependency)
          : base(dependency)
      { 
        _concreteDependency = dependency.ConcreteDependency;
      }
   }

কেন

  • শ্রেণিতে নতুন নির্ভরতা যুক্ত করা উত্পন্ন ক্লাসগুলিকে প্রভাবিত করে না
  • ক্লাসটি আইওসি কনটেইনারটির অজিনস্টিক
  • শ্রেণি বর্ণনামূলক (তার নির্ভরতার দিক থেকে)। কনভেনশন দ্বারা, আপনি যদি শ্রেণীর Aউপর নির্ভর করে তা জানতে চান , সেই তথ্যটি সঞ্চিতA.Dependency
  • কনস্ট্রাক্টর স্বাক্ষর সহজ হয়ে যায়

কেন না

  • অতিরিক্ত বর্গ তৈরি করা প্রয়োজন
  • পরিষেবা নিবন্ধকরণ জটিল হয়ে ওঠে (আপনাকে X.Dependencyআলাদা আলাদাভাবে নিবন্ধন করতে হবে )
  • ধারণাগতভাবে পাসের মত একই IoC Container
  • ..

সমাধান 2 কেবল একটি কাঁচা যদিও এর বিরুদ্ধে যদি কোনও শক্ত যুক্তি থাকে তবে বর্ণনামূলক মন্তব্যটি প্রশংসিত হবে


1

এটিই আমি ব্যবহার করি approach

public class Hero
{

    [Inject]
    private IInventory Inventory { get; set; }

    [Inject]
    private IArmour Armour { get; set; }

    [Inject]
    protected IWeapon Weapon { get; set; }

    [Inject]
    private IAction Jump { get; set; }

    [Inject]
    private IInstanceProvider InstanceProvider { get; set; }


}

ইঞ্জেকশনগুলি সঞ্চালন এবং মানগুলি ইনজেকশনের পরে কনস্ট্রাক্টর চালানো কীভাবে এখানে একটি অপ্রয়োজনীয় পদ্ধতি। এটি পুরোপুরি কার্যকরী প্রোগ্রাম।

public class InjectAttribute : Attribute
{

}


public class TestClass
{
    [Inject]
    private SomeDependency sd { get; set; }

    public TestClass()
    {
        Console.WriteLine("ctor");
        Console.WriteLine(sd);
    }
}

public class SomeDependency
{

}


class Program
{
    static void Main(string[] args)
    {
        object tc = FormatterServices.GetUninitializedObject(typeof(TestClass));

        // Get all properties with inject tag
        List<PropertyInfo> pi = typeof(TestClass)
            .GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
            .Where(info => info.GetCustomAttributes(typeof(InjectAttribute), false).Length > 0).ToList();

        // We now happen to know there's only one dependency so we take a shortcut just for the sake of this example and just set value to it without inspecting it
        pi[0].SetValue(tc, new SomeDependency(), null);


        // Find the right constructor and Invoke it. 
        ConstructorInfo ci = typeof(TestClass).GetConstructors()[0];
        ci.Invoke(tc, null);

    }
}

আমি বর্তমানে একটি শখের প্রকল্পে কাজ করছি যা এই https://github.com/Jokine/ToolProject/tree/Core এর মতো কাজ করে


-8

আপনি কোন নির্ভরতা ইনজেকশন কাঠামোটি ব্যবহার করছেন? আপনি কি এর পরিবর্তে সেটার ভিত্তিক ইনজেকশন ব্যবহার করার চেষ্টা করেছেন?

কন্সট্রাক্টর বেজড ইনজেকশনটির সুবিধা হ'ল এটি জাভা প্রোগ্রামারদের জন্য প্রাকৃতিক দেখাচ্ছে যা ডিআই ফ্রেমওয়ার্ক ব্যবহার করেন না। আপনার ক্লাস শুরু করার জন্য 5 টি জিনিস প্রয়োজন তবে আপনার কনস্ট্রাক্টরের পক্ষে আপনার 5 টি যুক্তি রয়েছে। নেতিবাচকতা যা আপনি লক্ষ্য করেছেন, এটি অতিরঞ্জিত হয়ে যায় যখন আপনার প্রচুর নির্ভরতা থাকে।

স্প্রিংয়ের সাথে আপনি পরিবর্তে সেটারগুলির সাথে প্রয়োজনীয় মানগুলি পাস করতে পারেন এবং আপনি ইঞ্জিন করা হয়েছে তা প্রয়োগ করতে @ প্রয়োজনীয় টীকাগুলি ব্যবহার করতে পারেন। অবক্ষয়টি হ'ল আপনাকে আর্টিকেশন কোডটি কনস্ট্রাক্টর থেকে অন্য পদ্ধতিতে সরিয়ে নেওয়া এবং স্প্রিং কল করতে হবে যে সমস্ত নির্ভরতা পরে @ পোস্টকন্সট্রাক্ট দিয়ে চিহ্নিত করে ইনজেকশন দেওয়া হয়। আমি অন্যান্য ফ্রেমওয়ার্ক সম্পর্কে নিশ্চিত নই তবে আমি ধরে নিই তারা এ জাতীয় কিছু করে do

উভয় পথই কাজ করে, এটি তার পছন্দের বিষয়।


21
কনস্ট্রাক্টর ইনজেকশনের কারণ হ'ল নির্ভরতা সুস্পষ্ট করা, এটি জাভা বিকাশকারীদের কাছে আরও প্রাকৃতিক দেখায় বলে নয়।
এল-ফোর

8
দেরিতে মন্তব্য করা, তবে এই উত্তরটি আমাকে হাসিয়ে দিয়েছে :)
ফ্রেডেরিক প্রিজক

1
সেটার ভিত্তিক ইনজেকশনগুলির জন্য +1। আমার ক্লাসে যদি পরিষেবাদি এবং সংগ্রহস্থলগুলি সংজ্ঞায়িত করা হয় তবে এটির নির্ভরতা হ'ল আমাকে বিশাল ভিবি 6 খুঁজছেন কনস্ট্রাক্টর লেখার দরকার নেই, এবং নির্মাত্রে নির্বোধ নির্ধারিত কোড করার দরকার নেই। প্রয়োজনীয় ক্ষেত্রগুলির মধ্যে নির্ভরতাগুলি কী তা খুব সুস্পষ্ট।
পাইটর কুলা

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