说我有以下课程
MyComponent : IMyComponent {
public MyComponent(int start_at) {...}
}
我可以通过xml通过城堡windsor注册它的实例,如下所示
<component id="sample" service="NS.IMyComponent, WindsorSample" type="NS.MyComponent, WindsorSample">
<parameters>
<start_at>1</start_at >
</parameters>
</component>
我将如何在代码中完成相同的操作? (注意,构造函数参数)
答案 0 :(得分:16)
编辑:使用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));
}
}
}
答案 1 :(得分:2)
试试这个
int start_at = 1;
container.Register(Component.For().DependsOn(dependency: Dependency.OnValue(start_at)));
答案 2 :(得分: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
您可以开始使用here。
答案 3 :(得分: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);
请注意,字典中的键值区分大小写。
答案 4 :(得分: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());
答案 5 :(得分:-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));
}
}
}