加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

winforms – 将Castle.Windsor与Windows窗体应用程序一起使用

发布时间:2020-12-13 20:30:35 所属栏目:Windows 来源:网络整理
导读:到目前为止,我一直在使用ASP.NET MVC学习使用Castle.Windsor的IoC / DI,但我有一个在Windows Forms中完成的辅助项目,我想知道是否有一种有效的方法来使用它那. 我的问题在于表单,服务等的创建.在ASP.NET MVC中,有一种“激活器”可以做到这一点,但在Windows窗
到目前为止,我一直在使用ASP.NET MVC学习使用Castle.Windsor的IoC / DI,但我有一个在Windows Forms中完成的辅助项目,我想知道是否有一种有效的方法来使用它那.

我的问题在于表单,服务等的创建.在ASP.NET MVC中,有一种“激活器”可以做到这一点,但在Windows窗体中并非如此.我必须创建一个像var form = new fclsMain();的新表单,所以一个像…

class fclsMain : System.Windows.Forms.Form
{
 private readonly ISomeRepository<SomeClass> someRepository;
 fclsMain(ISomeRepository<SomeClass> someRepository)
 {
  this.someRepository = someRepository;
 }
}

瀑布有点短.我基本上要做…

var form = new fclsMain(IoC.Resolve< ISomeRepository< SomeClass>);

正如我在至少三个问题中所指出的那样,并不聪明,因为据说这不是IoC的“正确”用法.

那么我如何使用Castle.Windsor和Windows Forms?有没有办法设计Form Activator或其他东西?我真的输了,如果我不能制作一个我可以解决的静态IoC容器,我该怎么办?

要在整个应用程序中使用相同的Castle容器,请创建一个静态类,如:
public static class CastleContainer {
    private static IWindsorContainer container;

    public static IWindsorContainer Instance {
        get {
            if (container == null) {
                container = new WindsorContainer();
            }
            return container;
        }
        // exposing a setter alleviates some common component testing problems
        set { container = value; }
    }

    // shortcut to make your life easier :)
    public static T Resolve<T>() {
        return Instance.Resolve<T>();
    }

    public static void Dispose() {
        if (container != null) 
            container.Dispose();
        container = null;
    }
}

然后在Main()方法中注册/安装所有组件.您还可以挂钩到应用程序关闭事件以调用Dispose()(尽管这并不重要).

Castle实际上在quick-start guide中使用了Windows Forms应用程序.

编辑:

我上面展示的模式是服务定位器的变体,有些人称之为反模式.它的声誉很差,因为除了其他原因之外,它还引用了Windsor的代码库.理想情况下,您应该只调用一次container.Resolve< ...>()来创建根表单.所有其他服务&形式通过构造函数注入.

实际上,您可能需要再调用一些Resolve,特别是如果您不想在启动时加载应用程序的每个角落.在Web世界中,最佳实践是将容器交给Web框架.在Windows窗体世界中,您需要实现自己的服务定位器,如上所述. (是的,将容器交给ASP.NET MVC框架仍然是服务定位器模式).

我编辑了上面的代码示例,以便静态容器是可注入的;没有资源在静态上下文中被束缚.如果您最终创建自己的服务定位器,您可能还需要创建一个像这样的测试实用程序,以使测试更容易.

public static class TestUtilities 
{
    public static IContainer CreateContainer(Action<IContainer> extraConfig = null) 
    {
        var container = new WindsorContainer();
        // 1. Setup common mocks to override prod configuration
        // 2. Setup specific mocks,when provided
        if (extraConfig != null)
            extraConfig(container);
        // 3. Configure container with production installers
        CastleContainer.Instance = container;
        return container;
    }
}

这使得创建一个看起来很像生产版本的新容器的快捷方式,但一些服务被模拟取代.一些示例测试可能如下所示:

[Test]
public void SubComponentWorksGreat() 
{
    using (var container = TestUtilities.CreateContainer())
    {
        var subComponent = container.Resolve<SubComponent>();
        // test it...
    }
}

[Test]
public void SubComponentWorksGreatWithMocks() 
{
    var repoMock = new Mock<IRepository>();
    using (var container = TestUtilities.CreateContainer(c => 
            c.Register(Component.For<IRepository>().Instance(repoMock.Object))))
    {
        var subComponent = container.Resolve<SubComponent>();
        // test it with all IRepository instances mocked...
    }
}

最后一点.为每个测试创建一个完整的容器可能会变得昂贵.另一种选择是创建完整容器,但仅使用嵌套容器进行实际测试.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读