windsor tutorial net .net castle-windsor

tutorial - castle.net core



Castle Windsor: ¿Cómo especificar un parámetro constructor a partir del código? (5)

Prueba esto

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

Digamos que tengo la siguiente clase

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

Puedo registrar una instancia de esto con castle windsor a través de xml de la siguiente manera

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

¿Cómo voy a hacer exactamente lo mismo pero en código? (Aviso, el parámetro constructor)


Necesitará pasar un IDictionary cuando solicite el contenedor para la instancia.

Utilizarías esta sobrecarga de Resolve del IWindsorContainer:

T Resolve<T>(IDictionary arguments)

o el no genérico:

object Resolve(Type service, IDictionary arguments)

Entonces, por ejemplo: (asumiendo que el contenedor es un IWindsorContainer)

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

Tenga en cuenta que los valores clave en el diccionario distinguen entre mayúsculas y minúsculas.


Editar: usé el código de las respuestas a continuación con la interfaz fluida :)

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)); } } }


Puede usar el método AddComponentWithProperties de la interfaz IWindsorContainer para registrar un servicio con propiedades extendidas.

A continuación se muestra una muestra de "trabajo" de hacer esto con una prueba de unidad 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)); } } }


¿Ha considerado usar Binsor para configurar su contenedor? En lugar de XML detallado y torpe, puede configurar Windsor usando un DSL basado en Boo. Así es como se verá tu configuración:

component IMyComponent, MyComponent: start_at = 1

La ventaja es que tiene un archivo de configuración maleable pero evita los problemas con XML. Además, no tiene que volver a compilar para cambiar su configuración como lo haría si configurara el contenedor en el código.

También hay muchos métodos de ayuda que permiten la configuración de cero fricción:

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

Puedes comenzar con esto aquí .