قلعة وندسور:كيفية تحديد معلمة منشئ من التعليمات البرمجية؟

StackOverflow https://stackoverflow.com/questions/87812

  •  01-07-2019
  •  | 
  •  

سؤال

لنفترض أن لدي الفصل التالي

MyComponent : IMyComponent {
  public MyComponent(int start_at) {...}
}

يمكنني تسجيل مثيل له في Castle Windsor عبر ملف XML على النحو التالي

<component id="sample"  service="NS.IMyComponent, WindsorSample" type="NS.MyComponent, WindsorSample">  
  <parameters>  
    <start_at>1</start_at >  
  </parameters>  
</component>  

كيف سأفعل نفس الشيء بالضبط ولكن في الكود؟(لاحظ، المعلمة المنشئ)

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

المحلول

يحرر:استخدم الإجابات أدناه الكود مع واجهة Fluent :)

namespace WindsorSample
{
    using Castle.MicroKernel.Registration;
    using Castle.Windsor;
    using NUnit.Framework;
    using NUnit.Framework.SyntaxHelpers;

    public class MyComponent : IMyComponent
    {
        public MyComponent(int start_at)
        {
            this.Value = start_at;
        }

        public int Value { get; private set; }
    }

    public interface IMyComponent
    {
        int Value { get; }
    }

    [TestFixture]
    public class ConcreteImplFixture
    {
        [Test]
        void ResolvingConcreteImplShouldInitialiseValue()
        {
            IWindsorContainer container = new WindsorContainer();

            container.Register(
                Component.For<IMyComponent>()
                .ImplementedBy<MyComponent>()
                .Parameters(Parameter.ForKey("start_at").Eq("1")));

            Assert.That(container.Resolve<IMyComponent>().Value, Is.EqualTo(1));
        }

    }
}

نصائح أخرى

جرب هذا

int start_at = 1; 
container.Register(Component.For().DependsOn(dependency: Dependency.OnValue(start_at)));

هل فكرت في استخدام Binsor لتكوين الحاوية الخاصة بك؟بدلاً من XML المطول والخرقاء، يمكنك تكوين Windsor باستخدام DSL يعتمد على Boo.إليك ما سيبدو عليه التكوين الخاص بك:

component IMyComponent, MyComponent:
   start_at = 1

الميزة هي أن لديك ملف تكوين مرن ولكن تجنب مشاكل XML.ليس عليك أيضًا إعادة الترجمة لتغيير التكوين الخاص بك كما تفعل إذا قمت بتكوين الحاوية في التعليمات البرمجية.

هناك أيضًا الكثير من الأساليب المساعدة التي تتيح تكوين الاحتكاك الصفري:

  for type in Assembly.Load("MyApp").GetTypes():
    continue unless type.NameSpace == "MyApp.Services"
    continue if type.IsInterface or type.IsAbstract or type.GetInterfaces().Length == 0
    component type.GetInterfaces()[0], type

يمكنك البدء به هنا.

تحتاج إلى تمرير معرف عندما تطلب من الحاوية الحصول على المثيل.

يمكنك استخدام حل التحميل الزائد لـ IWindsorContainer:

T Resolve<T>(IDictionary arguments)

أو غير عام:

object Resolve(Type service, IDictionary arguments)

لذلك، على سبيل المثال:(على افتراض أن الحاوية هي IWindsorContainer)

IDictionary<string, object> values = new Dictionary<string, object>();
values["start_at"] = 1;
container.Resolve<IMyComponent>(values);

لاحظ أن القيم الأساسية في القاموس حساسة لحالة الأحرف.

يمكنك استخدام فئة التكوين لقراءة ملف app.config.ثم قم بتسجيل ذلك واطلب من Windsor استخدامه لتبعيته.من الناحية المثالية، سيستخدم MyConfiguration واجهة.

public class MyConfiguration
{
    public long CacheSize { get; }

    public MyConfiguration()
    {
        CacheSize = ConfigurationManager.AppSettings["cachesize"].ToLong();
    }
}



container.Register(Component.For<MyConfiguration>().ImplementedBy<MyConfiguration>());

container.Register(Component.For<MostRecentlyUsedSet<long>>()
.ImplementedBy<MostRecentlyUsedSet<long>>().
DependsOn(Dependency.OnValue("size", container.Resolve<MyConfiguration>().CacheSize))
.LifestyleSingleton());

يمكنك استخدام الأسلوب AddComponentWithProperties لواجهة IWindsorContainer لتسجيل خدمة ذات خصائص موسعة.

يوجد أدناه نموذج "عملي" للقيام بذلك باستخدام اختبار وحدة NUnit.

namespace WindsorSample
{
    public class MyComponent : IMyComponent
    {
        public MyComponent(int start_at)
        {
            this.Value = start_at;
        }

        public int Value { get; private set; }
    }

    public interface IMyComponent
    {
        int Value { get; }
    }

    [TestFixture]
    public class ConcreteImplFixture
    {
        [Test]
        void ResolvingConcreteImplShouldInitialiseValue()
        {
            IWindsorContainer container = new WindsorContainer();
            IDictionary parameters = new Hashtable {{"start_at", 1}};

            container.AddComponentWithProperties("concrete", typeof(IMyComponent), typeof(MyComponent), parameters);

            IMyComponent resolvedComp = container.Resolve<IMyComponent>();

            Assert.That(resolvedComp.Value, Is.EqualTo(1));
        }

    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top