关于.net:Castle Windsor:如何从代码中指定构造函数参数?

关于.net:Castle Windsor:如何从代码中指定构造函数参数?

Castle Windsor: How to specify a constructor parameter from code?

说我有以下课程

1
2
3
MyComponent : IMyComponent {
  public MyComponent(int start_at) {...}
}

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

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

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


编辑:在Fluent界面中使用以下代码的答案:)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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));
        }

    }
}

尝试这个

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


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

1
2
component IMyComponent, MyComponent:
   start_at = 1

优点是您拥有可延展的配置文件,但避免了XML问题。另外,您不必重新编译即可更改配置,就像您在代码中配置容器一样。

还有许多辅助方法可以实现零摩擦配置:

1
2
3
4
  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

您可以在这里开始使用。


您可以使用配置类来读取app.config。然后注册并获得windsor对其依赖使用。理想情况下,我的MyConfiguration将使用接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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());

当您向容器询问实例时,您需要传递IDictionary。

您将使用IWindsorContainer的以下Resolve重载:

1
T Resolve< T >(IDictionary arguments)

或非通用的:

1
object Resolve(Type service, IDictionary arguments)

因此,例如:(假设容器是IWindsorContainer)

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

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


您可以使用IWindsorContainer接口的AddComponentWithProperties方法来注册具有扩展属性的服务。

以下是使用NUnit单元测试执行此操作的"有效"示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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));
        }

    }
}


推荐阅读

    程式编辑快捷键|代码编辑快捷键

    程式编辑快捷键|代码编辑快捷键,,1. 代码编辑快捷键Option Explicit ‘强制对模块内所有变量进行声明(2) Option Base 1 ‘指定数组的第一

    vivo网络设置代码|vivo功能代码

    vivo网络设置代码|vivo功能代码,,1. vivo功能代码代码是*#558#1.首先在手机桌面里找到电话。2.在拨号键盘里输入*#558#3.这时候就进入了手

    确定java按钮响应事件的代码

    确定java按钮响应事件的代码,,* 阅读本文可以结合最后在java登录窗口界面下面是一个链接。 是定义的容器。 容器(CP =得到内容面板); / /

    excel窗口快捷键|excel代码窗口快捷键

    excel窗口快捷键|excel代码窗口快捷键,,excel代码窗口快捷键首先是新建并打开Excel表格,萊垍頭條按快捷键“Ctrl”+“F10”,可把窗口切换,再

    乐视股票代码

    乐视股票代码,股票,股票代码,乐视股票代码股票代码其实很容易理解,每一串代码代表的就是一只股票,用“平安银行”来举例说明吧,它的代码就是0

    asp中文图片验证码的实现代码

    asp中文图片验证码的实现代码,,这个代码是在别人的增加对汉字的基础功能,谢谢你,谢谢轻烟。 以前的图片验证代码很容易破解,所以在目前的基础

    计算机主板故障调试代码

    计算机主板故障调试代码,,核心提示:故障代码含义查找表的调试代码查找表来读:(注1),特殊代码00和FF等起始码有三种情况:一系列其他代码:00或FF,好