11

说我有以下课程

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

我可以通过xml向城堡温莎注册它的一个实例,如下所示

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

我将如何在代码中做完全相同的事情?(注意,构造函数参数)

4

6 回答 6

16

编辑:使用流利界面​​的代码下面的答案:)

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

    }
}
于 2008-09-18T14:59:08.923 回答
2

试试这个

int start_at = 1; 
container.Register(Component.For().DependsOn(dependency: Dependency.OnValue(start_at)));
于 2014-10-14T14:30:42.963 回答
1

您是否考虑过使用 Binsor 来配置您的容器?您可以使用基于 Boo 的 DSL 来配置 Windsor,而不是冗长和笨拙的 XML。这是您的配置的样子:

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

您可以从这里开始。

于 2008-11-07T01:12:21.807 回答
0

当您向容器请求实例时,您需要传入一个 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);

请注意,字典中的键值区分大小写。

于 2008-09-17T21:32:27.097 回答
0

您可以使用配置类来读取 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());
于 2019-04-17T16:15:11.630 回答
-1

您可以使用 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));
        }

    }
}
于 2008-09-18T15:11:44.603 回答