说我有以下课程
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));
}
}
} |