3

我目前正在学习 Ninject 和依赖注入,在我当前的设置中,我将 IKernel 传递到一些地方,以便其他类可以实例化某些类或获取工厂实例。

目前我已经将我的工厂绑定为单例,并且将 IKernel 传递给一个对象然后这样做_kernel.Get<ISomethingFactory>().CreateSomething()似乎有点代码味道,只是将 Ninject 变成了一个美化的服务定位器。

此外,我的工厂正在传递 IKernel,因此他们可以解决他们创建的相应接口的绑定实现。

我的问题是:

  1. 是否允许工厂以这种方式运行,或者工厂是否应该简单地实例化具体类型本身?

  2. 我应该赞成通过构造函数传递工厂/其他服务,而不是到处传递 IKernel 吗?

4

1 回答 1

4

我不想……但这只是我。

另外,我不创建自己的工厂。我使用 Ninjects 工厂扩展。你可以在这里找到它:

https://github.com/ninject/ninject.extensions.factory

基本上,您可以像平常一样创建绑定,然后为工厂创建接口(假设此处为 WinForms):

public interface IMainFormFactory {
    frmLogin CreateLoginForm();
    frmSettings CreateSettingsForm();
    IRepository<MainFormModel> CreateMainFormRepository();
}

..并将其与ToFactory扩展名绑定:

using Ninject.Factories; // can't quite remember namespace at the moment

public class FactoryModule : NinjectModule {
    protected override void Load() {
        Bind<IMainFormFactory>().ToFactory();
    }
}

工厂扩展不需要你定义这个接口的具体实现。它已经知道如何根据你提供的绑定来处理这些对象(并且仍然会实例化你没有定义绑定的任何东西......例如表单。在幕后,它会为您创建一个实现此接口的管理器)。

那么,您可以执行以下操作:

private readonly IMainFormFactory _factory;

public frmMainForm(IMainFormFactory factory) {
    _factory = factory;
}

public void btnSettings_Click(object sender, EventArgs e) {
    // show the settings form..
    var settingsForm = _factory.CreateSettingsForm();
    settingsForm.ShowDialog();
}

..然后在 frmSettings 它也会注入:

public frmSettings(ISettingsFormFactory factory) {
    // as above except for ISettingsFactory
}

..这就是我选择做事的方式。也许其他人有更好的想法(我也有兴趣听到它们!)。

于 2012-12-11T04:42:23.607 回答