নির্ভরতা ইনজেকশন এবং পরিষেবা লোকেটার নিদর্শনগুলির মধ্যে পার্থক্য কী?


303

উভয় নিদর্শন নিয়ন্ত্রণের বিপরীতার নীতি বাস্তবায়নের মত বলে মনে হচ্ছে। এটি হল, যে কোনও অবজেক্টের তার নির্ভরতাগুলি কীভাবে তৈরি করা উচিত তা জানা উচিত নয়।

নির্ভরতা ইনজেকশন (ডিআই) এটির নির্ভরতা "ইনজেকশন" করতে কোনও নির্মাণকারী বা সেটার ব্যবহার করেছে।

কনস্ট্রাক্টর ইনজেকশন ব্যবহারের উদাহরণ:

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

পরিষেবা লোকেটার মনে হয় একটি "ধারক" ব্যবহার করে, যা এর নির্ভরশীলতাগুলিকে বাড়িয়ে তোলে এবং এটির বার দেয়।

পরিষেবা লোকেটার ব্যবহারের উদাহরণ:

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo()
  {
    this.bar = Container.Get<IBar>();
  }

  //...
}

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

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


13
নিয়ন্ত্রণের বিপরীতমুখীকরণের অর্থ হ'ল "কোনও বস্তুর কীভাবে তার নির্ভরতাগুলি কীভাবে তৈরি করা যায় তা জানা উচিত নয়"?!?!? এটি আমার কাছে নতুন। না, সত্যই, "নিয়ন্ত্রণের বিপরীতমুখীকরণ" এর অর্থ এটাই নয়। দেখুন martinfowler.com/bliki/InversionOfControl.html এই নিবন্ধটি এমনকি শব্দটির ব্যুৎপত্তি সম্পর্কিত রেফারেন্স সরবরাহ করে, ১৯৮০ এর দশক থেকে শুরু করে।
রোগারিও


1
মার্ক সিম্যান সার্ভিস লোকেটারকে অ্যান্টি-প্যাটার্ন হিসাবে যুক্ত করেছেন ( blog.ploeh.dk/2010/02/03/SCLLocatorisanAnti-Pattern )। এছাড়াও, আমি চিত্রটি পেয়েছি (এখানে পাওয়া গেছে, স্ট্যাকওভারফ্লো.com / a / 9503612 / 1977871 ) ডিআই এবং এসএল ভবিষ্যদ্বাণী বুঝতে সহায়তা করে। আশাকরি এটা সাহায্য করবে.
বিবেকদেব

উত্তর:


180

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


20
অতিরিক্তভাবে, বর্গ তৈরির সময় আপনি উভয়ই ব্যবহার করতে পারেন। ডিফল্ট কনস্ট্রাক্টর নির্ভরতা পুনরুদ্ধার করতে এসএল ব্যবহার করতে পারে এবং তাদের "প্রকৃত" কনস্ট্রাক্টারে পাস করতে পারে যা সেই নির্ভরতাগুলি গ্রহণ করে। আপনি উভয় বিশ্বের সেরা পেতে।
অনুদান পালিন

6
না, প্রদত্ত নির্ভরতা (প্লাগইন) এর জন্য সঠিক প্রয়োগটি ইনস্ট্যান্ট করার জন্য দায়বদ্ধ সার্ভিস লোকেশন। ডিআই-র ক্ষেত্রে, ডিআই "কনটেইনার" তার জন্য দায়ী।
রোগারিও

5
@ রোজারিও হ্যাঁ তবে ক্লাসটি এখনও সার্ভিস লোকেটার সম্পর্কে জানতে হবে ... দু'টি ছাড়িয়ে যায়। এছাড়াও প্রায়শই না আমি ডিআই কন্টেইনারে সার্ভিস লোকেটারের প্রতিনিধিকে বিশেষত ক্ষণস্থায়ী বস্তুর জন্য অনুসন্ধানের জন্য দেখেছি যার জন্য পরিষেবা সমর্থন প্রয়োজন।
অ্যাডাম জেন্ট

2
@ অ্যাডাম আমি বলিনি যে সার্ভিস লোকেটার একটি ডিআই কনটেইনারকে প্রেরণ করবে। "অফিসিয়াল" নিবন্ধে বর্ণিত হিসাবে এটি দুটি পারস্পরিক একচেটিয়া নিদর্শন । আমার কাছে, সার্ভিস লোকেটারটি অনুশীলনে ডিআই-র চেয়ে অনেক বেশি সুবিধা পেয়েছে: একটি ডিআই কনটেইনার ব্যবহারের জন্য অপব্যবহারের দাওয়াত দেওয়া হয় (যা আমি বারবার দেখেছি), যখন কোনও সার্ভিস লোকেটার ব্যবহার করে না।
Rogério

3
"এর একটি গুরুত্বপূর্ণ ফল হ'ল ডিআই উদাহরণটি ইউনিট পরীক্ষার পক্ষে অনেক সহজ - কারণ আপনি এটির উপর নির্ভরশীল অবজেক্টগুলির মক বাস্তবায়ন পাস করতে পারেন।" সত্য না. আপনার ইউনিট পরীক্ষায়, সার্ভিস লোকেটার পাত্রে কোনও রেজিস্টার ফাংশনে কল সহজেই রেজিস্ট্রিতে মক যোগ করতে ব্যবহার করা যেতে পারে।
ড্রামবেগ

92

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

একটি ভাল তুলনা: http://martinfowler.com আর্টিকেলস ইনজেকশন html

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


17
কিন্তু রানটাইম চলাকালীন আপনাকে কীভাবে এমন পরিস্থিতি পরিচালনা করবেন যেখানে আপনাকে অবজেক্ট তৈরি করতে হবে? আপনি যদি এগুলি ম্যানুয়ালি "নতুন" দিয়ে তৈরি করেন তবে আপনি ডিআই ব্যবহার করতে পারবেন না। যদি আপনি সহায়তার জন্য ডিআই ফ্রেমওয়ার্কটি কল করেন তবে আপনি প্যাটার্নটি ভঙ্গ করছেন। তাহলে কি বিকল্পগুলি বাকি আছে?
বরিস

9
@ বরিস আমার একই সমস্যা ছিল এবং ক্লাস নির্দিষ্ট কারখানাগুলি ইনজেকশনের সিদ্ধান্ত নিয়েছিলাম। সুন্দর নয় তবে কাজটি পেয়েছে। একটি সুন্দর সমাধান দেখতে পছন্দ করবে।
চার্লি রুডেনস্টাল

তুলনা করার জন্য সরাসরি লিঙ্ক: মার্টিনফাউলর
তেওম্যান শিপাহি

2
@ বরিস যদি আমাকে উড়তে নতুন অবজেক্টগুলি নির্মাণের প্রয়োজন হয় তবে আমি বলে থাকা অবজেক্টগুলির জন্য একটি বিমূর্ত কারখানাটি ইনজেকশন করব। যা এই ক্ষেত্রে কোনও সার্ভিস লোকেটার ইনজেকশনের অনুরূপ তবে প্রাসঙ্গিক বস্তু তৈরির জন্য একটি কংক্রিট, অভিন্ন, সংকলন-সময়, ইন্টারফেস সরবরাহ করে এবং নির্ভরতা সুস্পষ্ট করে তোলে।
লাইভপাস্ট E ই

51

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

তদ্ব্যতীত, সার্ভিস লোকেটারগুলি এনক্যাপসুলেশনটি ভেঙে দেয় কারণ তারা অন্যান্য সামগ্রীর নির্ভরতাতে বিশ্বব্যাপী অ্যাক্সেস সরবরাহ করে। যে কোনও সিঙ্গলটনের মতো সার্ভিস লোকেটার সহ :

ক্লায়েন্ট অবজেক্টের ইন্টারফেসের জন্য পূর্ব এবং পোস্টের শর্তাদি নির্দিষ্ট করা শক্ত হয়ে যায় কারণ এর বাস্তবায়নের কাজটি বাইরে থেকে মধ্যস্থতার করা যায়।

নির্ভরতা ইনজেকশন সহ, একবার কোনও বস্তুর নির্ভরতা নির্দিষ্ট হয়ে গেলে তারা নিজেই অবজেক্টের নিয়ন্ত্রণে থাকে।



2
আমি ওল 'স্টিভ ইয়েজকে ভালবাসি এবং সেই নিবন্ধটির শিরোনামটি দুর্দান্ত, তবে আমি মনে করি যে নিবন্ধটি আমি উদ্ধৃত করেছি এবং মিয়াকো হেভির "সিলেটলেটনগুলি প্যাথলজিকাল মিথ্যাবাদী" ( মিসকো. শেভরি.com/2008/08/17/singletons-are- pathological- মিথ্যাবাদী ) পরিষেবা লোকেটারের নির্দিষ্ট শয়তানের বিরুদ্ধে আরও ভাল কেস তৈরি করে।
জেফ স্টার্নাল

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

1
With dependency injection (at least constructor injection) the dependencies are explicit.। দয়া করে ব্যাখ্যা করুন.
করুনউইটিস্লামনিউ

উপরে হিসাবে, আমি দেখতে পাচ্ছি না যে কীভাবে এসএল নির্ভরতা ডিআই এর চেয়ে কম স্পষ্ট করে তোলে ...
মাইচা পাওয়ারকো

38

মার্টিন ফওলার বলেছেন :

পরিষেবা লোকেটারের সাথে অ্যাপ্লিকেশন ক্লাসটি স্পষ্টভাবে এটি লোকেটারের কাছে একটি বার্তার মাধ্যমে জিজ্ঞাসা করে। ইনজেকশন সহ কোনও সুস্পষ্ট অনুরোধ নেই, পরিষেবাটি ক্লাসে পরিষেবাটি উপস্থিত হয় - সুতরাং নিয়ন্ত্রণের বিপরীতমুখী।

সংক্ষেপে: সার্ভিস লোকেটার এবং ডিপেন্ডেন্সি ইনজেকশন হ'ল ডিপেন্ডেন্সি ইনভার্সন প্রিন্সিপালের কেবল বাস্তবায়ন।

গুরুত্বপূর্ণ নীতিটি হ'ল "অ্যাবস্ট্রাকশনের উপর নির্ভর করুন, কনক্রেশনের উপর নয়"। এটি আপনার সফ্টওয়্যার ডিজাইনটিকে "আলগাভাবে মিলিত", "এক্সটেনসিবল", "নমনীয়" করে তুলবে।

আপনি আপনার প্রয়োজনের সাথে সবচেয়ে উপযুক্ত ফিট ব্যবহার করতে পারেন। একটি বিশাল অ্যাপ্লিকেশনের জন্য, বিশাল কোডবেস থাকা, আপনি আরও ভালভাবে একটি সার্ভিস লোকেটার ব্যবহার করতে চাইবেন, কারণ নির্ভরতা ইনজেকশনটি আপনার কোডবেজে আরও পরিবর্তন প্রয়োজন।

আপনি এই পোস্টটি চেক করতে পারেন: নির্ভরতা বিপর্যয়: পরিষেবা লোকেটার বা নির্ভরতা ইনজেকশন

ক্লাসিক এছাড়াও: কন্ট্রোল কনটেইনারগুলির বিপরীতকরণ এবং মার্টিন ফওলারের নির্ভরতা ইনজেকশন প্যাটার্ন

পুনরায় ব্যবহারযোগ্য ক্লাস ডিজাইনিং রাল্ফ ই জনসন এবং ব্রায়ান ফুয়েটের পুনরায়

তবে, যে আমার চোখ খুলল সে হ'ল: এএসপি.নেট এমভিসি: সমাধান বা ইনজেকশন? ডিনো এস্পোসিতো দ্বারা ইস্যুটি ...


কল্পনাপ্রসূত সংক্ষিপ্তসার: "পরিষেবা লোকেটার এবং নির্ভরতা ইনজেকশন হ'ল নির্ভরতা বিপরীতমুখী মূলনীতিটির বাস্তবায়ন" "
হ্যান্স

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

1
সার্ভিস লোকেশন এবং ডিআইয়ের "নির্ভরতা বিপরীতমুখী নীতি" (ডিআইপি) এর সাথে কোনও সম্পর্ক নেই। ডিআইপি হ'ল একটি উচ্চ-স্তরের উপাদানটিকে আরও পুনঃব্যবহারযোগ্য করার একটি উপায়, উচ্চ স্তরের উপাদানটির সাথে একত্রে সংজ্ঞায়িত অ্যাবস্ট্রাক্ট টাইপের উপর নির্ভরশীলতা সহ একটি নিম্ন-স্তরের উপাদানটির উপর একটি সংকলন-সময় নির্ভরতা প্রতিস্থাপন করে, যা নিম্ন- স্তর উপাদান; এইভাবে, সংকলন-সময় নির্ভরতা উল্টে যায়, এখন এটি নিম্ন-স্তরের এক যা উচ্চ স্তরের একের উপর নির্ভর করে। এছাড়াও, মনে রাখবেন মার্টিন জালিয়া এর নিবন্ধ ব্যাখ্যা করেছেন যে যে দ্বি এবং আইওসির হয় না একই জিনিস।
Rogério

23

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

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

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


মজাদার! আমি ডিআই এবং এসএল উভয়ই ব্যবহার করছি তবে দুটি কনস্ট্রাক্টরের সাথে নয়। তিন বা চার সর্বাধিক বিরক্তির জন্য প্রায়শই নির্ভরশীলতার প্রয়োজন হয় (সেটিংস ইত্যাদি ...) ফ্লাইটের এসএল থেকে পান। অন্য সব কিছুই কন্সট্রাক্টর-ইনজেকশন পেয়ে যায়। এটি কিছুটা কুৎসিত, তবে বাস্তববাদী।
মার্টিনাস

10

উভয়ই আইওসি-র বাস্তবায়ন কৌশল। এছাড়াও অন্যান্য নিদর্শন রয়েছে যা নিয়ন্ত্রণের বিপরীতে প্রয়োগ করে:

  • কারখানার প্যাটার্ন
  • পরিষেবা লোকেটার
  • ডিআই (আইওসি) পাত্রে
  • নির্ভরতা ইনজেকশন (কনস্ট্রাক্টর ইঞ্জেকশন, প্যারামিটার ইঞ্জেকশন (প্রয়োজন না হলে), ইন্টারফেস ইনজেকশনের সেটার ইঞ্জেকশন) ...

পরিষেবা লোকেটার এবং ডিআই কনটেইনারটি আরও অনুরূপ বলে মনে হয়, উভয়ই নির্ভরতা নির্ধারণের জন্য একটি ধারক ব্যবহার করে, যা কংক্রিটের বাস্তবায়নের বিমূর্তিকে মানচিত্র করে।

মূল পার্থক্য হ'ল নির্ভরতাগুলি কীভাবে অবস্থিত হয়, সার্ভিস লোকেটারে, ক্লায়েন্ট কোড নির্ভরতাগুলির জন্য ডিআই কনটেইনারটিতে অনুরোধ করে আমরা সমস্ত বস্তু তৈরি করতে একটি ধারক ব্যবহার করি এবং এটি কনস্ট্রাক্টর পরামিতি (বা বৈশিষ্ট্য) হিসাবে নির্ভরতা ইনজেক্ট করে।


7

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

আপনি কীভাবে আপনার আইওসি পাত্রে নির্ভর করবেন না? হয় আপনাকে এটিকে নিজের করে আবদ্ধ করতে হবে (যা একটি খারাপ ধারণা) অথবা আপনি পরিষেবা লোকেটারটি আপনার আইওসি ধারকটি কনফিগার করতে ব্যবহার করেন। সুতরাং আপনি কোন সার্ভিস লোকেটারটি আপনাকে কোন ইন্টারফেসের প্রয়োজন তা জানাতে বলবেন এবং এটি ইন্টারফেসটি পুনরুদ্ধার করতে আইওসি কনটেইনারকে কল করবে।

আমার ক্ষেত্রে, আমি সার্ভিস লোকেটারটি ব্যবহার করি যা একটি কাঠামোর উপাদান। এবং আইওসি পাত্রে জন্য ইউনিটি ব্যবহার করুন। ভবিষ্যতে যদি আমার আইওসি ধারকটি নিনজেক্টে বদলাতে হয় করতে হয় তবে আমাকে Unক্যের পরিবর্তে নিনজেক্ট ব্যবহার করার জন্য আমার সার্ভিস লোকেটারটি কনফিগার করতে হবে। সহজ স্থানান্তর।

এখানে একটি দুর্দান্ত নিবন্ধ এই দৃশ্যের ব্যাখ্যা দেয়; http://www.johandekoning.nl/index.php/2013/03/03/dont-wrap-your-ioc-container/


জোহ্যান্ডেকোনিং নিবন্ধের লিঙ্কটি নষ্ট হয়েছে।
জেকজে

6

আমি মনে করি দুজন একসাথে কাজ করে।

নির্ভরতা ইনজেকশন মানে আপনি গ্রাহক শ্রেণিতে কিছুটা নির্ভরশীল শ্রেণি / ইন্টারফেসে চাপ দিন (সাধারণত এটি নির্মাণকারীর কাছে)। এটি একটি ইন্টারফেসের মাধ্যমে দুটি ক্লাসকে ডুপ্লুপ করে এবং এর অর্থ গ্রাহক শ্রেণি অনেক ধরণের "ইনজেকশন নির্ভরতা" বাস্তবায়ন নিয়ে কাজ করতে পারে।

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


6

যুক্ত করার একটি কারণ, আমরা গত সপ্তাহে এমইএফ প্রকল্পের জন্য একটি ডকুমেন্টেশন আপডেট দ্বারা অনুপ্রাণিত হয়েছি (আমি এমইএফ তৈরিতে সহায়তা করি)।

কোনও অ্যাপ্লিকেশন একবার সম্ভাব্য কয়েক হাজার উপাদান তৈরি হয়ে গেলে, কোনও নির্দিষ্ট উপাদান সঠিকভাবে ইনস্ট্যান্ট করা যায় কিনা তা নির্ধারণ করা কঠিন can "সঠিকভাবে ইনস্ট্যান্টিয়েটেড" দ্বারা, আমি বোঝাতে চাইছি যে এই উদাহরণটিতে Fooউপাদানটির উপর ভিত্তি করে একটি উদাহরণ IBarপাওয়া যাবে এবং পাওয়া যাবে এবং যে উপাদানটি এটি সরবরাহ করবে তা হ'ল:

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

দ্বিতীয় যে উদাহরণটি আপনি দিয়েছেন, যেখানে কনস্ট্রাক্টর আইওসি ধারকটির নির্ভরতা পুনরুদ্ধার করতে যায়, কেবলমাত্র আপনি যা পরীক্ষা করতে পারবেন যে আপনার অ্যাপ্লিকেশনটির আসল রানটাইম কনফিগারেশনটিFoo সঠিকভাবে ইনস্ট্যান্ট করতে সক্ষম হবে তা হ'ল প্রকৃতভাবে নির্মাণ করা এটা

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

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

একটি আইওসি পাত্রে, যখন সাবধানে ব্যবহার করা হয়, আসলে জড়িত উপাদানগুলির কোনও দৃষ্টান্ত তৈরি না করেই আপনার অ্যাপের রানটাইম কনফিগারেশনটি স্থিরভাবে বিশ্লেষণ করতে পারে। অনেক জনপ্রিয় পাত্রে এটির কিছুটা প্রকরণ সরবরাহ করে; মাইক্রোসফ্ট.কম্পেশন , যা এমইএফ টার্গেটিং। নেট 4.5 ওয়েব এবং মেট্রো স্টাইল অ্যাপ্লিকেশনগুলির সংস্করণ, CompositionAssertউইকি ডকুমেন্টেশনে একটি নমুনা সরবরাহ করে। এটি ব্যবহার করে, আপনি কোড লিখতে পারেন:

 // Whatever you use at runtime to configure the container
var container = CreateContainer();

CompositionAssert.CanExportSingle<Foo>(container);

( এই উদাহরণ দেখুন )।

পরীক্ষার সময় আপনার অ্যাপ্লিকেশনটির সংশ্লেষের মূলগুলি যাচাই করে আপনি সম্ভবত কিছু ত্রুটিগুলি ধরতে পারেন যা অন্যথায় প্রক্রিয়াতে পরীক্ষার মাধ্যমে পিছলে যেতে পারে।

আশা করি এটি অন্যথায় এই বিষয়ের উপর জবাবের সেটগুলিতে একটি আকর্ষণীয় সংযোজন!


5

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

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

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

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

এটিকে কোনও পরিষেবা লোকেটার (বা কেবলমাত্র লোকেটার) হিসাবে উল্লেখ করা হয়, বা আইওসি পাত্রে (বা কেবল ধারক হিসাবে) কোনও পার্থক্য রাখে না কারণ আপনার অনুমান হিসাবে তারা সম্ভবত একই বিমূর্তির উল্লেখ করছেন (ভুল হলে আমাকে সংশোধন করুন) )। এটাকে কেবল পরিষেবা লোকেটার বলা হলে বোঝা যায় যে কেউ নির্ভর করে ইঞ্জেকশন প্যাটার্নের সাথে সার্ভিস লোকেটারকে অ্যান্টি-প্যাটার্ন ব্যবহার করছে।

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


4

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


4
হুম আমি একমত নই: সার্ভিস লোকেটার প্রাক্তন। পরিষ্কারভাবে দেখায় যে সেখানে এখনও একটি নির্ভরতা রয়েছে ... পরিষেবা লোকেটার। যদি barক্লাসের নিজেই নির্ভরতা থাকে তবে barসেবার সার্ভিস লোকেটারও থাকবে, এটি ডিআই / আইওসি ব্যবহারের পুরো বিষয়।
GFoley83

2

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

নির্ভরতা ইনজেকশন প্যাটার্নটি স্বাক্ষর করার কারণে কোনও ক্লাসের (বা কোনও পদ্ধতি) যে নির্ভরতাগুলি নির্ভর করছে তা পরিষ্কার করে দেয়। এই কারণে, ফলাফলযুক্ত কোডটি ক্লিনার এবং আরও পঠনযোগ্য।


1

সাধারণ ধারণার পরে নিম্নলিখিতটি আমাকে পরিষেবা লোকেটার এবং ডিআই কনটেইনারগুলির মধ্যে পার্থক্য সম্পর্কে আরও পরিষ্কার ধারণা দিয়েছে:

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

  • ডিআই কনটেইনারটি বাইরে কোথাও অবস্থিত এবং এটি কিছু স্টোরেজ থেকে পরিষেবা গ্রহণ করে এবং গ্রাহকের কাছে ঠেলা দেয় (কনস্ট্রাক্টরের মাধ্যমে বা পদ্ধতির মাধ্যমে নয়)

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


0

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


-2

রেকর্ড এর জন্য

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

আপনার যদি সত্যই ইন্টারফেসের প্রয়োজন না হয় (ইন্টারফেসটি একাধিক শ্রেণীর দ্বারা ব্যবহৃত হয়), আপনি এটি ব্যবহার করবেন না । এই ক্ষেত্রে, আইবার যে কোনও পরিষেবা শ্রেণিকে ব্যবহার করে, এটি প্রয়োগ করে। তবে, সাধারণত, এই ইন্টারফেসটি একটি একক শ্রেণীর দ্বারা ব্যবহৃত হবে।

ইন্টারফেস ব্যবহার করা খারাপ ধারণা কেন ?. কারণ এটি ডিবাগ করা সত্যিই কঠিন।

উদাহরণস্বরূপ, আসুন বলি যে উদাহরণটি "বার" ব্যর্থ হয়েছে, প্রশ্ন: কোন শ্রেণিতে ব্যর্থ হয়েছে ?. আমার কোন কোডটি ঠিক করা উচিত? একটি সাধারণ দর্শন, এটি একটি ইন্টারফেসে নিয়ে যায় এবং এখানেই আমার রাস্তা শেষ হয়।

পরিবর্তে, যদি কোডটি কোনও হার্ড নির্ভরতা ব্যবহার করে তবে একটি ভুল ডিবাগ করা সহজ।

//Foo Needs an IBar
public class Foo
{
  private BarService bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

যদি "বার" ব্যর্থ হয়, তবে আমার ক্লাসে বার সার্ভিসটি পরীক্ষা করা উচিত fir


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