শিরোনামটি "সার্কুলার নির্ভরতা" বলেছে, তবে এটি সঠিক শব্দের নয়, কারণ আমার কাছে নকশাটি শক্ত মনে হয়েছে।
তবে নীচের পরিস্থিতিটি বিবেচনা করুন, যেখানে নীল অংশগুলি বাহ্যিক অংশীদার থেকে দেওয়া হয় এবং কমলা আমার নিজস্ব বাস্তবায়ন। ধরে নিও এর পরে আরও কিছু রয়েছে 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));
}
}