캐슬 윈저:코드에서 생성자 매개변수를 지정하는 방법은 무엇입니까?

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

  •  01-07-2019
  •  | 
  •  

문제

다음 수업이 있다고 가정 해 보겠습니다.

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

다음과 같이 XML을 통해 Castle Windsor에 인스턴스를 등록할 수 있습니다.

<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 대신 Boo 기반 DSL을 사용하여 Windsor를 구성할 수 있습니다.구성은 다음과 같습니다.

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

당신은 그것으로 시작할 수 있습니다 여기.

컨테이너에 인스턴스를 요청할 때 IDictionary를 전달해야 합니다.

IWindsorContainer의 Resolve 오버로드를 사용합니다.

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

IWindsorContainer 인터페이스의 AddComponentWithProperties 메서드를 사용하여 확장 속성이 있는 서비스를 등록할 수 있습니다.

다음은 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