我使用Castle。温莎图书馆,我想要的是获得"实现"属性,从IRegistration[]中的所有项目。
我有以下接口和类:
public interface IA
{
int a { get; set; }
}
public class A : IA
{
public int a { get; set; }
}
public interface IB
{
int b { get; set; }
}
public class B : IB
{
public int b { get; set; }
}
和一个包含以下组件的静态类:
public static class Bootekstraperek
{
private static readonly IRegistration[] _commonRegistrations =
{
Component.For<IA>().ImplementedBy<A>(),
Component.For<IB>().ImplementedBy<B>()
};
public static void Test()
{
List<IRegistration> list = _commonRegistrations.ToList();
foreach (var registration in list)
{
ComponentRegistration a = registration as ComponentRegistration;
Console.WriteLine(a.Implementation.FullName);
}
}
}
当然变量a在每次迭代后都是空的。它只在转换为Generic ComponentRegistration
时起作用var a = registration as ComponentRegistration<A>;
但是,这不能帮助我,如果我有太多不同的组件在这个数组。所以Switch语句不是一个选项。我试过使用反射,但我仍然没有设法正确投射。
我怎样才能达到我想要的与或不使用反射?
thxia .
这并不容易,因为IRegistration
API从未打算以这种方式使用。
所以我的回答有两个部分。
- 怎么做?使用
dynamic
你只需要修改一小部分代码:
foreach (dynamic registration in list)
{
Console.WriteLine(registration.Implementation.FullName);
}
- 你想要达到的潜在目标是什么?如果您的目标是保持对注册内容的可见性,如何注册并注意潜在问题,请查看Windsor的诊断。
少量的Reflection解决了这个问题(它是少量的,但它看起来很冗长,因为Reflection):
foreach (var registration in list)
{
Console.WriteLine(
((Type)registration.GetType().GetProperty(
"Implementation"
).GetGetMethod().Invoke(
registration,new object[] { })
).FullName);
}
因为在运行时之前你不会知道被用作泛型类型参数的类型,所以我认为没有任何反射是无法做到这一点的。
上面假设所有的注册将是某种
ComponentRegistration<T>
对象。如果这是一个不安全的假设,可能有一些IRegistration
的其他实现不实现Implementation
属性或它可能不是公开访问-所以插入适当的临时错误检查,如果是这种情况。