0

我有一个使用 MVP 模式的 Windows 窗体应用程序。每个视图都是一个 WinForms 用户控件,并由处理非 UI 问题的演示者支持。该应用程序使用 Castle Windsor,所有视图呈现器和许多其他组件都通过 Windsor Container 解决。

我想做的是为用户控件视图自定义属性注入。我的观点并没有大量使用属性注入,但它偶尔会非常有用并且效果很好。问题是,我的用户控件通常包含嵌套控件,而嵌套控件又可以包含其他嵌套控件,并且属性注入不适用于这些嵌套控件,因为它们不是通过容器直接解决的。

我想做的是为从 SWFControl类继承的组件配置属性注入。除了在组件上查找属性之外,我还想在嵌套控件(在Controls)集合中查找属性,并将其注入到这些嵌套属性中。

我知道 Castle Windsor 非常灵活且可配置,因此这可能是可能的。不过,我需要在正确的方向上稍微推动一下。这可能吗?有没有人试图做类似的事情?

4

1 回答 1

1

如果我正确理解了您的问题,我认为实现您想要的唯一方法是通过某种穷人的依赖注入(是的,有争议的 - 请不要对我投反对票!)因为 winforms 设计器生成方法的方式构造您所说的各种子控件,这对 IoC 毫无帮助。

我不确定你是否能够进行属性注入,但你可以使用构造函数,这是我刚刚炮制的一个脑筋急转弯的方案......

首先,创建一些方法来访问您的 Windsor 容器——这样的事情可能会奏效:

public static class MyContainer
{
    private static readonly IWindsorContainer _container = Bootstrap();

    // I did it like this so that there is no explicit dependency
    // on Windsor - this would be the only place you need to change
    // if you want an alternate container (how much you care about
    // that is up to you)
    public static T Resolve<T>()
    {
        return _container.Resolve<T>();
    }

    private static IWindsorContainer Bootstrap()
    {
        var container = new WindsorContainer();
        container.Install(FromAssembly.This());

        // ... whatever else you need to do here

        return container;
    }
}

其次,在内部控件中,您希望注入一些属性执行类似的操作(我选择了好的 ol' ILogger 作为您可能想要注入的示例):

public partial class MyFancyControl : UserControl
{    
    // Constructor to keep the winforms designer happy
    public MyFancyControl() 
        : this (MyContainer.Resolve<ILogger>())
    {
        // Intentionally always blank as this 
        // is an un-unit-testable method
    }

    // Constructor that does the actual work
    public MyFancyControl(ILogger logger)
    {
        InitializeComponent();
        Logger = logger;
    }

    public ILogger Logger { get; private set; }
}

注意:使用记录器会引发一些明显的气味之一 - 有时您根本没有向容器注册这样的组件(通常您有一个空记录器),因此您可能需要连接某种机制那个,但如果你需要它,我把它留给你。

于 2012-07-04T13:30:05.427 回答