আমি নির্ভরতা ইনজেকশন পাই, তবে কেউ কি আমাকে আইওসি পাত্রে প্রয়োজনীয়তা বুঝতে সাহায্য করতে পারে?


15

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

আমি সাধারণত আমার ব্যবসায়িক যুক্তিটি এমন কোনও শ্রেণিতে বিভক্ত করি যা দেখতে এরকম কিছু দেখায়:

public class SomeBusinessOperation
{
    private readonly IDataRepository _repository;

    public SomeBusinessOperation(IDataRespository repository = null)
    {
        _repository = repository ?? new ConcreteRepository();
    }

    public SomeType Run(SomeRequestType request)
    {
        // do work...
        var results = _repository.GetThings(request);

        return results;
    }
}

সুতরাং এটির কেবলমাত্র একটি নির্ভরতা রয়েছে এবং কিছু ক্ষেত্রে এটিতে দ্বিতীয় বা তৃতীয় হতে পারে, তবে প্রায়শই এটি হয় না। সুতরাং যাকে এটিকে ডাকে এটি নিজস্ব রেপো পাস করতে পারে বা এটি ডিফল্ট রেপো ব্যবহারের অনুমতি দেয় allow

আইওসি ধারক সম্পর্কে আমার বর্তমান উপলব্ধি যতদূর যায়, সমস্ত কন্টেইনারটি হ'ল IDataRepository সমাধান করুন। তবে যদি এটি সমস্ত কিছু করে তবে আমি এর মধ্যে এক টন মূল্য দেখছি না যেহেতু আমার অপারেশনাল ক্লাসগুলি ইতিমধ্যে কোনও ফ্যালব্যাক সংজ্ঞায়িত করে যখন কোনও নির্ভরতা পাস হয় না So সুতরাং আমি কেবলমাত্র অন্যান্য সুবিধাটিই ভাবতে পারি যে যদি আমার বেশ কয়েকটি অপারেশন থাকে তবে এটি একই ফ্যালব্যাক রেপো ব্যবহার করে, আমি সেই রেপোটিকে এক জায়গায় পরিবর্তন করতে পারি যা রেজিস্ট্রি / কারখানা / ধারক। এবং এটি দুর্দান্ত, তবে এটি কি?


1
প্রায়শই নির্ভরতার ডিফল্ট ফ্যালব্যাক সংস্করণ থাকা আসলেই অর্থবোধ করে না।
বেন অ্যারসন

আপনি কী বলতে চাইছেন? "ফ্যালব্যাক" হ'ল কংক্রিট শ্রেণি যা ইউনিট পরীক্ষা বাদে বেশিরভাগ সময় ব্যবহৃত হয়। কার্যত, এটি ধারকটিতে নিবন্ধিত একই শ্রেণি হবে।
সিনেটেস্ট্যাটিক

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

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

আমি একটি টিশার্ট তৈরি করতে যাচ্ছি যাতে "ফাংশন প্যারামিটারগুলি - মূল নির্ভরতা ইনজেকশন!"
গ্রাহাম

উত্তর:


2

আইওসি কন্টেইনারটি সেই ক্ষেত্রে সম্পর্কিত নয় যেখানে আপনার একটি নির্ভরতা রয়েছে। এটি আপনার ক্ষেত্রে 3 টি নির্ভরতা রয়েছে এবং এটির বেশ কয়েকটি নির্ভরতা রয়েছে তার ক্ষেত্রে এটি about

এটি নির্ভরশীলতার রেজোলিউশন এবং নির্ভরতাগুলির জীবনচক্র পরিচালনাকে কেন্দ্রিয় করতে আপনাকে সহায়তা করে।


10

আপনি আইওসি পাত্রে ব্যবহার করতে পারেন এমন বিভিন্ন কারণ রয়েছে।

অবাস্তব dlls

আপনি নির্বিঘ্নিত dll থেকে কংক্রিটের ক্লাসটি সমাধান করতে IoC ধারক ব্যবহার করতে পারেন। এর অর্থ হ'ল আপনি সম্পূর্ণ বিমূর্ততা - অর্থাৎ ইন্টারফেসের উপর নির্ভরতা নিতে পারেন।

এর ব্যবহার এড়িয়ে চলুন new

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

বিমূর্ততা বিরুদ্ধে লিখুন

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

ভঙ্গুর কোড এড়িয়ে চলুন

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

লাইফটাইম ম্যানেজমেন্ট এবং অপরিশোধিত রিসোস ক্লিনআপ

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

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


22
এই আইওসি পাত্রে সুবিধা নয়, তারা নির্ভরতা ইনজেকশনের সুবিধা, যা দরিদ্র মানুষের ডিআই দিয়ে সহজেই করা যায়
বেন অ্যারনসন

আইওসি পাত্রে না রেখে ভাল ডিআই কোড লেখা আসলে বরং কঠিন হতে পারে। হ্যাঁ, সুবিধাগুলিতে কিছু ওভারল্যাপ রয়েছে তবে আইওসি ধারক দিয়ে এগুলি সবথেকে ভালভাবেই ব্যবহার করা হয়েছে।
স্টিফেন

ঠিক আছে, আমার মন্তব্যটি যেহেতু আপনি যুক্ত করেছেন তার শেষ দুটি কারণগুলি আরও ধারক-নির্দিষ্ট এবং উভয়ই আমার মতে খুব
দৃ argu়

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

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

2

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

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

উদাহরণস্বরূপ এই নীতিগুলির সংমিশ্রণ (নিম্ন মানের কোডের জন্য দুঃখিত, আমি সি # এর পরিবর্তে কিছু অ্যাড-হক ভাষা ব্যবহার করেছি, যেহেতু আমি এটি জানি না):

  1. কোনও এসআরপি নেই, আইওসি নেই

    class SomeHighLevelService
    {
        public doFooBar(){
            Crap crap = doFoo();
            doBar(crap);
        }
    
        public Crap doFoo(){
            //...
            return crap;
        }
    
        public doBar(Crap crap){
            //...
        }
    }
    
    SomeHighLevelService service = new SomeHighLevelService();
    service.doFooBar();
  2. এসআরপির কাছাকাছি, কোনও আইওসি নেই

    class SomeHighLevelService
    {
        public SomeHighLevelService(){
            Foo foo = new Foo();
            Bar bar = new Bar();
        }
    
        public doFooBar(){
            Crap crap = foo.doFoo();
            bar.doBar(crap);
        }
    }
    
    class Foo {
        public Crap doFoo(){
            //...
            return crap;
        }
    }
    
    class Bar {
        public doBar(Crap crap){
            //...
        }
    }
    
    SomeHighLevelService service = new SomeHighLevelService();
    service.doFooBar();
  3. হ্যাঁ এসআরপি, কোনও আইওসি নেই

    class HighLevelServiceProvider {
        public SomeHighLevelService getSomeHighLevelService(){
            SomeHighLevelService service = new SomeHighLevelService();
            service.setFoo(this.getFoo());
            service.getBar(this.getBar());
            return service;
        }
    
        private Foo getFoo(){
            return new Foo();
        }
    
        private Bar getBar(){
            return new Bar();
        }
    }
    
    class SomeHighLevelService
    {           
        public setFoo(Foo foo){
            this.foo = foo;
        }
    
        public setBar(Bar bar){
            this.bar = bar;
        }
    
        public doFooBar(){
            Crap crap = foo.doFoo();
            bar.doBar(crap);
        }
    
    }
    
    class Foo {
        public Crap doFoo(){
            //...
            return crap;
        }
    }
    
    class Bar {
        public doBar(Crap crap){
            //...
        }
    }
    
    HighLevelServiceProvider provider = new HighLevelServiceProvider();
    SomeHighLevelService service = provider.getSomeHighLevelService();
    service.doFooBar();
  4. হ্যাঁ এসআরপি, হ্যাঁ আইওসি

    interface HighLevelServiceProvider {
        SomeHighLevelService getSomeHighLevelService();
    }
    
    interface SomeHighLevelService {
        doFooBar();
    }
    
    interface Foo {
        Crap doFoo();
    }
    
    interface Bar {
        doBar(Crap crap);
    }
    
    
    class ConcreteHighLevelServiceContainer implements HighLevelServiceProvider {
        public SomeHighLevelService getSomeHighLevelService(){
            SomeHighLevelService service = new ConcreteHighLevelService();
            service.setFoo(this.getFoo());
            service.getBar(this.getBar());
            return service;
        }
    
        private Foo getFoo(){
            return new ConcreteFoo();
        }
    
        private Bar getBar(){
            return new ConcreteBar();
        }
    }
    
    class ConcreteHighLevelService implements SomeHighLevelService
    {           
        public setFoo(Foo foo){
            this.foo = foo;
        }
    
        public setBar(Bar bar){
            this.bar = bar;
        }
    
        public doFooBar(){
            Crap crap = foo.doFoo();
            bar.doBar(crap);
        }
    
    }
    
    class ConcreteFoo implements Foo {
        public Crap doFoo(){
            //...
            return crap;
        }
    }
    
    class ConcreteBar implements Bar {
        public doBar(Crap crap){
            //...
        }
    }
    
    
    HighLevelServiceProvider provider = new ConcreteHighLevelServiceContainer();
    SomeHighLevelService service = provider.getSomeHighLevelService();
    service.doFooBar();

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.