winforms Castle温莎for Windows Form中的自订属性插入

z9gpfhce  于 2022-11-16  发布在  Windows
关注(0)|答案(1)|浏览(142)

我 有 一 个 使用 MVP 模式 的 Windows 窗体 应用 程序 。 每个 视图 都 是 一 个 WinForms 用户 控件 , 并 由 一 个 处理 非 UI 问题 的 表示 器 支持 。 该 应用 程序 使用 Castle Windsor , 所有 视图 表示 器 和 许多 其他 组件 都 通过 Windsor 容器 解析 。
我 希望 能够 为 用户 控件 视图 自 定义 属性 注入 。 我 的 视图 并 没有 大量 使用 属性 注入 , 但 它 偶尔 会 非常 有用 并且 工作 得 很 好 。 问题 是 , 我 的 用户 控件 经常 包含 嵌套 控件 , 而 嵌套 控件 又 可以 包含 其他 嵌套 控件 , 属性 注入 对 这些 嵌套 控件 不 起 作用 。因为 它们 不是 通过 容器 直接 解析 的 。
我 想 做 的 是 为 从 SWF Control 类 继承 的 组件 配置 属性 注入 。 除了 查找 组件 上 的 属性 外 , 我 还 想 查找 嵌套 控件 ( 在 Controls 集合 中 ) 上 的 属性 , 并 注入 到 这些 嵌套 属性 中 。
我 知道 城堡 温莎 是 非常 灵活 和 可 配置 的 , 所以 这 可能 是 可能 的 。 我 需要 一 点 推动 在 正确 的 方向 虽然 。 这 是 可能 的 吗 ? 有人 尝试 过 做 类似 的 事情 吗 ?

uoifb46i

uoifb46i1#

如果我没有理解错你的问题,我认为实现你想要的唯一方法是通过某种穷人的依赖注入,因为winforms设计器生成一个方法来构造你所说的各种子控件的方式使它与IoC毫无关系。
我不确定你是否能够做属性注入,但是你可以利用构造函数,这是我刚刚炮制的一个愚蠢的方案...
首先,创建某种方式来访问您的温莎容器-类似于以下内容的方式可能会起到作用:

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; }
}
  • 注意:使用logger会引起一些明显的问题--有时候你根本不用容器注册这样的组件(通常你有一个空logger),所以你可能需要连接某种机制,但是我把它留给你自己决定是否需要。*

相关问题