নির্ভরতা ইনজেকশনে কীভাবে "বিজ্ঞপ্তি নির্ভরতা" পরিচালনা করবেন


15

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

দৃশ্যপট

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

IUnityContainer ioc = new UnityContainer();
ioc.RegisterType<IMain, ConcreteMain>()
   .RegisterType<IMainCallback, Runner>();
var runner = ioc.Resolve<Runner>();

আমি কীভাবে এটিকে উপার্জন করতে পারি? এটির গঠনের কোনও উপায় কি যাতে আমি এটি ডিআই-র সাথে ব্যবহার করতে পারি? আমি এখন যে দৃশ্যটি করছি তা হ'ল ম্যানুয়ালি সবকিছু সেট আপ করছে তবে ConcreteMainএটি ক্লাসে একটি দৃ depend় নির্ভরশীলতা রাখে যা এটি ইনস্ট্যান্ট করে তোলে। এটিই আমি এড়াতে চাইছি (কনফিগারেশনে ityক্য নিবন্ধের সাথে)।

নীচের সমস্ত উত্স কোড (খুব সরল উদাহরণ!);

public class Program
{
    public static void Main(string[] args)
    {
        IUnityContainer ioc = new UnityContainer();
        ioc.RegisterType<IMain, ConcreteMain>()
           .RegisterType<IMainCallback, Runner>();
        var runner = ioc.Resolve<Runner>();

        Console.WriteLine("invoking runner...");
        runner.DoSomethingAwesome();

        Console.ReadLine();
    }
}

public class Runner : IMainCallback
{
    private readonly IMain mainServer;

    public Runner(IMain mainServer)
    {
        this.mainServer = mainServer;
    }

    public void DoSomethingAwesome()
    {
        Console.WriteLine("trying to do something awesome");
        mainServer.DoSomething();
    }

    public void SomethingIsDone(object something)
    {
        Console.WriteLine("hey look, something is finally done.");
    }
}

public interface IMain
{
    void DoSomething();
}

public interface IMainCallback
{
    void SomethingIsDone(object something);
}

public abstract class AbstractMain : IMain
{
    protected readonly IMainCallback callback;

    protected AbstractMain(IMainCallback callback)
    {
        this.callback = callback;
    }

    public abstract void DoSomething();
}

public class ConcreteMain : AbstractMain
{
    public ConcreteMain(IMainCallback callback) : base(callback){}

    public override void DoSomething()
    {
        Console.WriteLine("starting to do something...");
        var task = Task.Factory.StartNew(() =>{ Thread.Sleep(5000);/*very long running task*/ });
        task.ContinueWith(t => callback.SomethingIsDone(true));
    }
}

উত্তর:


10

আপনি যা করতে পারেন তা হ'ল মেইনফ্যাক্টরি একটি কারখানা তৈরি করা যা কংক্রিটমাইনের একটি প্রতিচ্ছবি আইমন হিসাবে ফেরত দেয়।

তারপরে আপনি নিজের রানার কনস্ট্রাক্টরে এই কারখানাটি ইনজেক্ট করতে পারেন। কারখানার সাথে মেইন তৈরি করুন এবং প্যারামিটার হিসাবে নিজেই উত্তরণ করুন।

কংক্রিটমেন কনস্ট্রাক্টরের উপর অন্য যে কোনও নির্ভরতা আইওসির মাধ্যমে মাইমেনফ্যাক্টরিতে প্রবেশ করতে এবং ম্যানুয়ালি কংক্রিট কনস্ট্রাক্টরের দিকে ঠেলা যায়।

public class MyMainFactory
{
    MyOtherDependency _dependency;

    public MyMainFactory(MyOtherDependency dependency)
    {
        _dependency = dependency;
    }

    public IMain Create(Runner runner)
    {
        return new ConcreteMain(runner, _dependency);
    }
}

public class Runner
{
    IMain _myMain;
    public Runner(MyMainFactory factory)
    {
        _myMain = factory.Create(this)
    }
}

4

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


4

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


4

ইউনিটি 3 এর সাথে, আপনি এখন ইনজেকশন করতে পারেন Lazy<T> । এটি কোনও কারখানা / অবজেক্ট ক্যাশে ইনজেকশনের অনুরূপ।

কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনি আপনার সিটরে কাজ করছেন না যার জন্য অলস নির্ভরতা সমাধানের প্রয়োজন।

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