سؤال

أخيرا، أحصل على قدمي الرطب مع حقن التبعية (طال انتظار)؛ لقد بدأت اللعب بالوحدة وتدير مشكلة في نمط الاستراتيجية. يمكنني استخدام الحاوية للعودة إلي عن تطبيقات محددة لاستراتيجية بناء على اسم، ولكن ما لا أرى هو كيف من المفترض أن أحصل على الاستراتيجية الصحيحة في السياق.
دعنا نوضح في مثال بسيط: السياق هو سيارة، والتي لديها IENGINE (الاستراتيجية)، مع تطبيقين، Firstengine و STINGINE. سوف ينظر القانون إلى جانب هذه الخطوط:

public interface IEngine
{
    double MaxSpeed
    {
        get;
    }
}

internal class FastEngine:IEngine
{
    public double MaxSpeed
    {
        get 
        { 
            return 100d; 
        }
    }
}

internal class SlowEngine:IEngine
{
    public double MaxSpeed
    {
        get
        {
            return 10d;
        }
    }
}

public class Car
{
    private IEngine engine;
    public double MaximumSpeed
    {
        get
        {
            return this.engine.MaxSpeed;
        }
    }

    public Car(IEngine engine)
    {
        this.engine = engine;
    }
}

مشكلتي هي ما يلي: كيف يجب أن أذهب حول إنشاء سيارة سريعة أو سيارة بطيئة؟ يمكنني استخدام الحاوية لتزويدني بكل تطبيق، ويمكنني تعيين تطبيق "افتراضي" لاستخدامه:

IUnityContainer container = new UnityContainer();
container.RegisterType<IEngine, FastEngine>();
container.RegisterType<IEngine, FastEngine>("Fast");
container.RegisterType<IEngine, SlowEngine>( "Slow" );
var car = container.Resolve<Car>();
Assert.AreEqual(100, car.MaximumSpeed);

ولكن ما أود أن أتمكن من طلب سيارة مع تنفيذ معين للاستراتيجية - شيء مثل

var car = container.Resolve<Car>(??? use "Fast" or "Slow ???);

هل يمكنني استخدام الحاوية للقيام بذلك؟ أو يجب أن أكتب المصنع الذي يستخدم الحاوية؟ سيكون موضع تقدير أي إرشادات - لست متأكدا من أنني أفكر في هذا الأمر!

هل كانت مفيدة؟

المحلول

نمط شائع في دي هو ذلك في وقت التشغيل سيكون هناك فقط تنفيذ واحد لجراجة معينة. هذا فقط يجعل الحياة أسهل بكثير، لأنك لا تحتاج إلى التعامل مع الغموض مثل الشخص الذي تصفه.

ومع ذلك، في بعض الأحيان، تحتاج إلى تغيير التنفيذ بناء على السياق، مثل المثال الذي تقدمه. توفر العديد من حاويات DI طرقا حيث يمكنك تقديم معلمة مؤهلة، ولكن هذا يعني أنك ستنتهي بك الأمر بإحكام اقتران التعليمات البرمجية الخاصة بك إلى حاوية DI محددة.

سيكون حلا أفضل بكثير لتقديم مصنع مجردة يمكن أن توفر ما تحتاجه. شيء مثل

public interface ICarFactory
{
    Car Create(IEngine engine);
}

إذا كنت بحاجة إلى ضخ المزيد من الاستراتيجيات، وربما باني نمط التصميم قد يصلح أفضل.

في أي حال، فإن النقطة هي أنه بدلا من تسجيل الكثير من السيارات المختلفة في الحاوية، فإنك تقوم بدلا من ذلك بتسجيل تنفيذ احترافي واحد.

في رمز العميل الخاص بك، ستستخدم Icarfactory حقن لإنشاء مثيل سيارة بناء على IENGINE معين.

var car = factory.Create(engine);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top