0
public class A
{
    public X x { get; set; }
}

public class B
{
    public X x { get; set; }
}

public class X
{
    public X(object owner) { /* ... */ }
}

基本上,如果类AB在 Windsor 中注册,我希望能够以X这样的方式解决依赖关系,即它获取所需的类的实例。

在纯代码中,它看起来像这样:

var a = new A();
var x = new X(a);
a.X = x;

温莎有没有办法做到这一点,也许是通过一些可扩展性机制?


即使对我来说,这看起来也是一个疯狂的问题,所以这背后有一些动机:

上面的X示例ITracer中的代理TraceSource是为每个跟踪的消息添加一些信息,即所有者的唯一 ID 及其类型(现在它只是 ID - 这就是问题的原因 - 我无法得到到实例并调用GetType()它)。

一个简单的例子使它更清楚。假设您有一些服务IService,并希望以最非侵入性的方式向它添加跟踪。但是在应用程序中可能有十几个此服务的实例,因此在跟踪中您希望通过 ID/类型来区分它们。如果类从容器接收它的跟踪器并在需要时在那里写消息,而不考虑 ID、具体TraceSource等,那就太好了。

我已经有一些基础设施可以让我这样写:

[TracedTo("NameOfTheTraceSource")]
public class Service : IService
{
    public ITracer Tracer { get; set; }
}

并且 Windsor 正确地解析Tracer为它自己的(不与其他对象共享)ITracer指向TraceSourcename的实例NameOfTheTraceSource。此外,如果我添加traceAllMethods = true到属性 - Windsor 将自动添加拦截器,它将通过相同的方式记下此实例上的每个方法调用Tracer(并且仅在相应TraceSource配置了一些侦听器时才会这样做 - 我们不必支持将它们添加到飞)。这真是太棒了,因为它不需要开发人员提供任何东西Service,并且在不需要时不会降低性能,一点也不。所以我正在努力让这更方便:)

4

1 回答 1

1

好的,我想你想要的是一个设施。这是一个简单的(没有错误检查),可能是您正在寻找的(或至少为您指明正确的方向):

public class XFacility : AbstractFacility
{
    protected override void Init()
    {
        this.Kernel.ComponentCreated += KernelOnComponentCreated;
    }

    private void KernelOnComponentCreated(ComponentModel model, object instance)
    {
        var props =
            instance.GetType().GetProperties().Where(p => p.CanWrite && p.PropertyType == typeof (X));
        if (props.Any())
        {
            var pi = props.First();
            pi.SetValue(instance, new X(instance), null);
        }
    }
}

现在确保在进行任何解析之前将设施添加到容器中:

var container = new WindsorContainer();
container.AddFacility<XFacility>();
container.Register(Component.For<A>(),
                    Component.For<B>()
    );

var a = container.Resolve<A>();
于 2012-12-12T05:26:19.660 回答