使用 ninject 进行 WinForms 对话框的最佳实践是什么?

发布于 2024-09-14 05:12:38 字数 1435 浏览 2 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

a√萤火虫的光℡ 2024-09-21 05:12:38

我将使依赖关系处于表单到表单的级别。你想要介于两者之间的东西。

namespace Example
{
    public class SettingsRepository
    {
        public SettingsRepository()
        {

        }
    }
    public class SettingsForm
    {
        private SettingsRepository _settingsRepository;
        public SettingsForm( SettingsRepository settingsRepository )
        {
            _settingsRepository = settingsRepository;

        }
    }
    public class MainForm
    {
        private SettingsRepository _settingsRepository;
        private Func<SettingsForm> _createSettingsForm;
        public MainForm( Func<SettingsForm> createSettingsForm, SettingsRepository settingsRepository )
        {
            _createSettingsForm = createSettingsForm;
            _settingsRepository = settingsRepository;

        }
    }
}

然后,您将 Func 注入到您的类中,以从代码中删除对容器/内核的直接使用(如果您在整个过程中进行内联 Get 调用)地方,你正在做服务定位,这与 DI 完全不同)。

    public class ExampleNinjectModule : NinjectModule
    {
        public override void Load()
        {
            Bind<Func<SettingsForm>>().ToMethod( context => () => context.Kernel.Get<SettingsForm>()  );
        }
    }

另一种方法是向构造函数参数添加一个Kernel(Ninject 会自动解析它),但这很快就会变得一团糟。

我尝试快速搜索示例,但遗憾的是没有在 WinForms 空间中快速找到任何内容。我建议也许寻找 WPF 示例。

最重要的是,如果您满足以下条件,您就不会犯大错:

  1. 坚持构造函数注入,并尽可能避免在实际代码中直接使用内核或容器属性
  2. 不使用全局内核和/或服务位置

更新 Sep 12:这些天一肯定会使用 Ninject.Extensions.Factory 来管理工厂(即上面的大部分代码将在幕后自动生成)

I would make the dependency be at the form-to-form level. You want to have something in between that.

namespace Example
{
    public class SettingsRepository
    {
        public SettingsRepository()
        {

        }
    }
    public class SettingsForm
    {
        private SettingsRepository _settingsRepository;
        public SettingsForm( SettingsRepository settingsRepository )
        {
            _settingsRepository = settingsRepository;

        }
    }
    public class MainForm
    {
        private SettingsRepository _settingsRepository;
        private Func<SettingsForm> _createSettingsForm;
        public MainForm( Func<SettingsForm> createSettingsForm, SettingsRepository settingsRepository )
        {
            _createSettingsForm = createSettingsForm;
            _settingsRepository = settingsRepository;

        }
    }
}

Then you inject a Func<SettingsForm> into your class to remove the direct usage of the container / Kernel from your code (if you're doing inline Get calls all over the place, you're doing Service Location, which is a different thing to DI entirely).

    public class ExampleNinjectModule : NinjectModule
    {
        public override void Load()
        {
            Bind<Func<SettingsForm>>().ToMethod( context => () => context.Kernel.Get<SettingsForm>()  );
        }
    }

Another approach is to add a Kernel to your constructor args (Ninject automatically resolves it), but that quickly becomes a mess in general.

I tried a quick search for samples, but sadly didnt find anything quickly in the WinForms space. I'd suggest perhaps looking for WPF examples instead.

Bottom line is you wont go far wrong if you:

  1. stick with Constructor Injection, and avoiding direct usage of Kernel or container attributes in your real code as much as possible
  2. Dont use a Global Kernel and/or Service Location

Update Sep 12: These days one would definitely employ Ninject.Extensions.Factory to manage the factory (i.e., most of the code would above would be auto-genned behind the scenes)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文