Castle Windsor: كيف يمكنني تحديث تسجيل مكونات
-
06-09-2019 - |
سؤال
إذا كنت قد حددت في التكوين:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName }))
.LifeStyle.Transient
);
وأتمنى تمديد هذا التكوين وإضافة عنصر جديد إلى خاصية صفيف المستمعين بحيث يكون التكوين النهائي فعليا:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName, "MyOtherListenerID" }))
.LifeStyle.Transient
);
يجب أن أعرف محتويات "الصفيف" عند تسجيل المكون لأول مرة، أو هل يمكنني استرجاع تسجيل المكون وإضافة إليه؟
أود أن أقوم بتطبيق التكوين الخاص بي باستخدام نمط Decorator بحيث يمكنني بناء حاوية بلدي، ثم تمديده حسب الحاجة لسيناريوهات مختلفة. هذا يعني أنني بحاجة إلى أن أكون قادرا على الوصول إلى المكونات التي تم تكوينها بالفعل وأضفها إليهم.
كان يفكر في وجود فصل DefaultConfig
الذي إرجاع الإعداد الافتراضي ثم واحد من أكثر "DecoratedConfig
"الفصول، من شأنها أن تمتد التكوين الافتراضي.
لذلك سيكون لدي
IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer();
DefaultConfig
سوف إعداد ActivityService
مع DefaultActivityListener
(كما هو مبين في المثال).
DecoratedConfig
سوف ندرك ذلك ActivityService
قد تم إنشاؤها وإضافة تنفيذ المستمع الخاص بها إلى Listeners
صفيف على ActivityService
.
شكرا.
المحلول
اشترك في Kernel.ComponentModelCreated
حدث. يمكنك تغيير أي معلمة مكون من هناك. يرى هذه. وبعد غير ذلك يملك أن تكون منشأة يفعل هذا، لكنها مريحة.
نصائح أخرى
maustch، يحيط ComponentModel
يبدو أن التكوين هو الحل.
الاختبار أدناه يفعل بشكل فعال بما أحتاج دون الحاجة إلى ربط ComponentModelCreatedEvent
لذلك يمكنني إجراء التغييرات حتى بعد إنشاء نموذج المكون.
سوف ألتف الوظيفة كطريقة تمديد، وحاول وتناسب واجهة برمجة تطبيقات بطلاقة.
[TestMethod]
public void ArrayPropertyTestApi3()
{
using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer())
{
container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(new[] { typeof(Components.B).FullName })));
container.Register(Component.For<Components.B>());
container.Register(Component.For<Components.C>());
IHandler h = container.Kernel.GetHandler(typeof(Components.A));
if (h != null)
{
var config = h.ComponentModel.Configuration;
if (config != null)
{
var items = config.Children.Single(c => c.Name == "parameters")
.Children.Single(c => c.Name == "I")
.Children.Single(c => c.Name == "list")
as MutableConfiguration;
items.Children.Add(new MutableConfiguration("item", string.Format("${{{0}}}", typeof(Components.C).FullName)));
}
}
Components.A svc = container.Resolve<Components.A>();
Assert.IsTrue(svc.I.Length == 2);
Assert.IsTrue(svc.I[0].Name == "B");
Assert.IsTrue(svc.I[1].Name == "C");
}
}
من الأفضل استخدام ComponentModel مساهمي البناء مع ال IContributeComponentModelConstruction
واجهة لأنها هي الطريقة الموصى بها في تكوين مكوناتك أكثر.
للقيام بذلك، سوف تقوم بتنفيذ الواجهة لتحديد التغييرات التي يجب تطبيقها على التكوين
public class ChangeConfiguration : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
// filter your model to match the subset you're interested in
// change the configuration for matching models
}
}
ثم قبل تسجيل مكوناتك، يمكنك فقط إضافة الفصل إلى الحاوية الخاصة بك:
container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration());
ستمر جميع المكونات بعد ذلك عبر هذه الفئة، حيث يمكنك تغيير تكوينها. في حالتك تغيير قائمة المستمع، إلخ (أعتقد أن هذا هو الاسم السابق لعقد اعتراضي)