使用Castle Windsor创建具有循环关系的组件 [英] Create components with circular relationships using Castle Windsor

查看:58
本文介绍了使用Castle Windsor创建具有循环关系的组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个有限状态机,每个类都代表一个状态。每个状态都知道它可以转换到哪些其他状态,这自然会导致循环关系。 (请参见状态设计模式)。

I'm implementing a finite-state machine, with each class representing a state. Each state knows which other states it can transition to, and this naturally leads to circular relationships. (See the State Design Pattern).

对于这个简化的示例,我创建两个组件,其中第一个组件引用第二个组件,第二个组件引用第一个组件。

For this simplified example I'm creating two components, where the first component has a reference to the second component, and the second component has a reference to the first.

问题在于,温莎框架正确地为第一个创建的组件设置了引用,但没有为第二个组件设置引用:

The problem is that the Windsor framework is correctly setting the references for the first created component, but not setting the references for the second:

这是两个组件:

// DefaultMouseHandler knows about NewLineMouseHandler
public class DefaultMouseHandler : MouseHandler
{
    public DefaultMouseHandler()
    {
    }

    public NewLineMouseHandler NewLineMouseHandler
    {
        get;
        set;
    }

    internal override MouseHandler LeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
    {
        return this.NewLineMouseHandler;
    }
}


// NewLineMouseHandler knows about DefaultMouseHandler
public class NewLineMouseHandler : MouseHandler
{
    public NewLineMouseHandler()
    {
    }

    public DefaultMouseHandler DefaultMouseHandler
    {
        get;
        set;
    }

    internal override MouseHandler LeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
    {
        return this.DefaultMouseHandler;
    }
}

然后我将组件注册为:

_windsorContainer.Register(Classes.FromThisAssembly()
                                 .BasedOn<MouseHandler>()
                         );

但是当我第一次尝试创建 DefaultMouseHandler :

But when I first attempt to create the DefaultMouseHandler:


  • 构造 DefaultMouseHandler

  • NewLineMouseHandler 已构建

  • NewLineMouseHandler DefaultMouseHandler

  • The DefaultMouseHandler is constructed
  • The NewLineMouseHandler is constructed
  • The NewLineMouseHandler is set on the DefaultMouseHandler

但是 DefaultMouseHandler NewLineMouseHandler 上未设置c>。

But the DefaultMouseHandler is NOT set on the NewLineMouseHandler.

可以认为这是温莎城堡的缺陷吗?

Can this be considered a defect in Castle Windsor?

使两个组件相互引用而又没有一个组件知道Windsor容器的最佳方法是什么?

What's the best way to have the two components referencing each other, without either component being aware of the Windsor container?

推荐答案

我提出的解决方案是使用 TypedFactoryFacility

The solution I've come up with is to use the TypedFactoryFacility.

这允许按原样创建对象

public interface IMouseHandlerFactory
{
    T CreateHandler<T>() where T : MouseHandler;
}

// In the registration code
_windsorContainer.AddFacility<TypedFactoryFacility>();
_windsorContainer.Register(Classes.FromThisAssembly()
                               .BasedOn<MouseHandler>(),
                           Component.For<IMouseHandlerFactory>()
                                    .AsFactory()
                          );

// The base class
public abstract class MouseHandler
{
    // Every mousehandler will create at least one other mouse handler
    // This is the factory that they will use for mouse handling creation
    // The property will be automatically set by the DI container
    public IMouseHandlerFactory MouseHandlerFactory { get; set; }

    // Methods the concrete implementations will override
    internal virtual MouseHandler LeftButtonDown(MouseButtonEventArgs e) { return this; }
    internal virtual MouseHandler LeftButtonUp(MouseButtonEventArgs e) { return this; }
}   

// The implementations
public class DefaultMouseHandler : MouseHandler
{
    internal override MouseHandler LeftButtonDown(MouseButtonEventArgs e)
    {
        return this.MouseHandlerFactory.CreateHandler<NewLineMouseHandler>();
    }
}

public class NewLineMouseHandler : MouseHandler
{
    internal override MouseHandler LeftButtonUp(MouseButtonEventArgs e)
    {
        return this.MouseHandlerFactory.CreateHandler<DefaultMouseHandler>();
    }
}

这篇关于使用Castle Windsor创建具有循环关系的组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆