ইনজেকশন নির্ভরতাগুলি কর্টর বা প্রতি পদ্ধতিতে করা উচিত?


16

বিবেচনা:

public class CtorInjectionExample
{
    public CtorInjectionExample(ISomeRepository SomeRepositoryIn, IOtherRepository OtherRepositoryIn)
    {
        this._someRepository = SomeRepositoryIn;
        this._otherRepository = OtherRepositoryIn;
    }

    public void SomeMethod()
    {
        //use this._someRepository
    }

    public void OtherMethod()
    {
        //use this._otherRepository
    }
}

বিরুদ্ধে:

public class MethodInjectionExample
{
    public MethodInjectionExample()
    {
    }

    public void SomeMethod(ISomeRepository SomeRepositoryIn)
    {
        //use SomeRepositoryIn
    }

    public void OtherMethod(IOtherRepository OtherRepositoryIn)
    {
        //use OtherRepositoryIn
    }
}

যখন Ctor ইনজেকশনটি এক্সটেনশনটিকে কঠিন করে তোলে (নতুন নির্ভরতা যুক্ত হওয়ার সাথে সাথে কোডারে কল করা কোনও কোড আপডেট করার প্রয়োজন হবে) এবং পদ্ধতি স্তরের ইনজেকশনটি ক্লাস স্তরের নির্ভরতা থেকে আরও এনক্যাপসুলেটেড বলে মনে হয় এবং আমি এই পদ্ধতির জন্য / বিপরীতে অন্য কোনও যুক্তি খুঁজে পাই না can't ।

ইনজেকশন গ্রহণ করার জন্য একটি নির্দিষ্ট উপায় আছে?

(এনবি আমি এ সম্পর্কিত তথ্যের সন্ধান করেছি এবং এই প্রশ্নটিকে উদ্দেশ্যমূলক করার চেষ্টা করেছি))


4
যদি আপনার ক্লাসগুলি সমন্বিত হয়, তবে বিভিন্ন ক্ষেত্রগুলি একই ক্ষেত্র ব্যবহার করবে। এটি আপনাকে যে উত্তরটি
চেয়েছে

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

: উদাহরণ আমি দিয়েছি জন্য প্রাসঙ্গিক en.wikipedia.org/wiki/False_dilemma
StuperUser

উত্তর:


3

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


15

ঠিক আছে, প্রথমে বন্ধ করুন, "নতুন নির্ভরতা যুক্ত হওয়ার সাথে সাথে কোডারকে কল করা যে কোনও কোড আপডেট করার দরকার পড়বে"; স্পষ্টতই, যদি আপনি নির্ভরতা ইনজেকশন করছেন এবং নির্ভরতার সাথে কোনও বস্তুতে আপনার কাছে নতুন () কল করার কোনও কোড রয়েছে, আপনি এটি ভুল করছেন

আপনার ডিআই কনটেইনারটি সমস্ত প্রাসঙ্গিক নির্ভরশীলতাগুলি ইনজেকশনে সক্ষম হতে হবে, তাই আপনাকে কনস্ট্রাক্টর স্বাক্ষর পরিবর্তন করার বিষয়ে চিন্তা করার দরকার নেই, যাতে যুক্তিটি সত্যই ধরে না।

প্রতি-পদ্ধতি বনাম প্রতি ক্লাস ইনজেকশন ধারণা হিসাবে, প্রতি-পদ্ধতিতে ইঞ্জেকশন নিয়ে দুটি বড় সমস্যা রয়েছে।

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

পরবর্তী সমস্যাটি হ'ল প্রতি-পদ্ধতিতে নির্ভরতাগুলি "ইনজেকশন" করতে, আপনাকে সেগুলি পদ্ধতি কলের মধ্যে প্রেরণ করতে হবে। এর অর্থ হল যে পদ্ধতি কলের আগে আপনাকে নির্ভরতাগুলি সমাধান করতে হবে, সুতরাং আপনি সম্ভবত কোডের একগুচ্ছ দিয়ে শেষ করবেন:

var someDependency = ServiceLocator.Resolve<ISomeDependency>();
var something = classBeingInjected.DoStuff(someDependency);

এখন, বলুন যে আপনি আপনার অ্যাপ্লিকেশনটির আশেপাশে 10 জায়গায় এই পদ্ধতিটি কল করতে চলেছেন: আপনার কাছে এই 10 টি স্নিপেট থাকবে। এরপরে, বলুন যে আপনাকে ডস্ট স্টাফের () আরও একটি নির্ভরতা যুক্ত করতে হবে: আপনাকে সেই স্নিপেটটি 10 ​​বার পরিবর্তন করতে হবে (বা কোনও পদ্ধতিতে এটি মোড়ানো হবে) এই ক্ষেত্রে আপনি কেবল ডিআই আচরণটি ম্যানুয়ালি প্রতিলিপি করছেন, যা নষ্ট সময়)।

সুতরাং, আপনি সেখানে মূলত যা করেছেন তা আপনার ডিআই-ব্যবহারকারী শ্রেণিকে তাদের নিজস্ব ডিআই কনটেইনার সম্পর্কে সচেতন করে তুলেছে, যা একটি মৌলিকভাবে খারাপ ধারণা , কারণ এটি খুব তাড়াতাড়ি একটি ক্লানকি ডিজাইনের দিকে পরিচালিত করে যা বজায় রাখা কঠিন।

কনস্ট্রাক্টর ইঞ্জেকশনের সাথে এর তুলনা করুন; কনস্ট্রাক্টর ইনজেকশনে আপনি কোনও নির্দিষ্ট ডিআই কনটেইনার সাথে আবদ্ধ হন না এবং আপনি কখনই আপনার ক্লাসের নির্ভরতা পূরণের জন্য সরাসরি দায়বদ্ধ হন না, তাই রক্ষণাবেক্ষণ মোটামুটি মাথা ব্যথা মুক্ত is

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

(এনবি আমি আপনার আগে যে পদ্ধতির পরামর্শ দিচ্ছিলাম তা করেছি এবং এটি আমার পক্ষে খুব খারাপ ধারণা ছিল যা আমি এর পরে পুনরাবৃত্তি করি নি Turn ইন্টারফেসগুলির একটি সেট সহ যেখানে প্রতিটি পদ্ধতি কলটিতে অন্যান্য ইন্টারফেসগুলির একটি কাছাকাছি স্থির নির্বাচন প্রয়োজন maintain এটি বজায় রাখা দুঃস্বপ্ন।)


1
"if you're doing dependency injection and you have any code calling new() on an object with dependencies, you're doing it wrong."আপনি যদি ক্লাসে কোনও পদ্ধতিতে ইউনিট পরীক্ষা করছেন তবে আপনাকে এটি ইনস্ট্যান্ট করতে হবে বা আপনি নিজের কোড টেস্টের অধীনে ইনস্ট্যান্ট করতে ডিআই ব্যবহার করেন?
স্টুপার ইউজার

@ স্টুপার ইউজার ইউনিট টেস্টিং কিছুটা ভিন্ন দৃশ্য, আমার মন্তব্যটি কেবলমাত্র উত্পাদন কোডের জন্য প্রযোজ্য। যেহেতু আপনি একটি পরীক্ষামূলক কাঠামোর মাধ্যমে আপনার পরীক্ষার জন্য মক (বা স্টাব) নির্ভরতা তৈরি করতে যাচ্ছেন, প্রতিটি প্রাক-কনফিগার করা আচরণ এবং অনুমান এবং দৃser়তার সেট সহ, আপনাকে এগুলি হাতে ইনজেকশন করতে হবে।
এড জেমস

1
আমি যখন "any code calling the ctor will need updating"বলি তখন কোডটিই আমার কোড কোডটি কল করে না। এসব কারণে.
StuperUser

2
@ স্টুপার ইউজার ফেয়ার পর্যাপ্ত, তবে আপনি এখনও প্রয়োজনীয় নির্ভরতাগুলির সাথে পদ্ধতিগুলি কল করতে যাচ্ছেন, যার অর্থ আমার বাকী উত্তর এখনও দাঁড়িয়ে আছে! সত্যি কথা বলতে, আমি ইউনিট পরীক্ষার দৃষ্টিকোণ থেকে কনস্ট্রাক্টর ইনজেকশন এবং সমস্ত নির্ভরতা জোর করে বিষয়টি নিয়ে সম্মত। আমি সম্পত্তি ইনজেকশন ব্যবহার করার প্রবণতা রাখি, কারণ এটি আপনাকে পরীক্ষার জন্য প্রত্যাশা করা নির্ভরতাগুলি কেবলমাত্র ইনজেকশনের অনুমতি দেয়, যা আমি পাই যে মূলত অন্তর্নিহিত Assert এর আরও একটি সেট isওয়াসট নট কল্ট কলগুলি আসলে কোনও কোড না লিখেই রয়েছে! : ডি
এড জেমস

3

বিভিন্ন ধরণের নিয়ন্ত্রণের বিপরীততা রয়েছে এবং আপনার প্রশ্নে কেবল দুটি প্রস্তাব দেয় (আপনি নির্ভরতা ইনজেক্ট করতে কারখানাও ব্যবহার করতে পারেন)।

উত্তরটি: এটি প্রয়োজনের উপর নির্ভর করে। কখনও কখনও এক ধরণের এবং অন্য ধরণের ব্যবহার করা ভাল।

আমি ব্যক্তিগতভাবে কনস্ট্রাক্টর ইনজেক্টর পছন্দ করি, যেহেতু কনস্ট্রাক্টর সেখানে অবজেক্টটিকে পুরোপুরি আরম্ভ করার জন্য উপস্থিত থাকে। পরে একটি সেটার কল করার পরে অবজেক্টটি পুরোপুরি নির্মিত না হয়।


3

আপনি যেটি মিস করেছেন তা কমপক্ষে আমার জন্য সবচেয়ে নমনীয় - সম্পত্তি ইনজেকশন। আমি ক্যাসেল / উইন্ডসর ব্যবহার করি এবং আমাকে যা করতে হবে তা হ'ল আমার ক্লাসে একটি নতুন অটো সম্পত্তি যুক্ত করা এবং আমি কোনও সমস্যা ছাড়াই এবং কোনও ইন্টারফেস না ভেঙে ইনজেকশনের বস্তুটি পাই।


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

আমি সম্পত্তি ইঞ্জেকশনটিও পছন্দ করি, কেবলমাত্র আপনি এখনও ডিআই কনটেইনার দিয়ে সাধারণ কনস্ট্রাক্টর প্যারামিটারগুলি ব্যবহার করতে পারেন, স্বয়ংক্রিয়ভাবে সমাধান হওয়া এবং অ-সমাধানকৃত নির্ভরতার মধ্যে পার্থক্য। তবে কনস্ট্রাক্টর হিসাবে- এবং সম্পত্তি-ইনজেকশনটি এই দৃশ্যের জন্য কার্যত অভিন্ন, আমি এটি উল্লেখ না করা বেছে নিয়েছি;)
এড জেমস

সম্পত্তি ইনজেকশন প্রতিটি বস্তুকে পরিবর্তনীয় হতে বাধ্য করে এবং একটি অবৈধ অবস্থায় উদাহরণ তৈরি করে। কেন যে ভাল হবে?
ক্রিস পিটম্যান

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