【问题标题】:How do I provide extra parameters with Ninject?如何使用 Ninject 提供额外的参数?
【发布时间】:2019-04-03 05:09:53
【问题描述】:

我需要自动解决我的 windows 窗体的依赖关系。唯一的问题是我的表单构造函数也需要一个整数值。请看代码部分的实现。

   //Ninject bindings
   public class Bindings : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<LogToDB>();
            Bind<ICopy>().To<CopyToFolder>();            
        }
    }

  //WinForm - Form1
   public partial class Form1 : Form
    {
        public readonly ILogger _processRepository;
        public readonly Icopy _copy;
        public readonly int ValueToEdit;
        public Form1(int valueToEdit, ILogger logger, ICopy copy)
        {
            this._processRepository = logger;
            this._copy = copy;
            this.ValueToEdit = valueToEdit;
            InitializeComponent();
        }
    }
    //main
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        IKernel kernel = new StandardKernel(new Bindings());            
        Application.Run(kernel.Get<Form1>());            
    }

我收到一个错误: Ninject.ActivationException: '错误激活 int 没有匹配的绑定可用,并且类型不是自绑定的。

我怎样才能自动解决表单依赖关系,也能传递整数值?实际上,我使用相同的表单来添加和编辑,所以在编辑时,应该设置这个编辑值。

【问题讨论】:

  • 顺便说一句,您的问题实际上与 Windows 窗体无关。这真的是“我如何为 ninject 提供额外的参数?”您的问题可能与this one 重复。
  • 更改了问题的标题。
  • @John,在我的例子中,构造函数的值只是一个整数,只有在加载表单时才能知道它的值。
  • 防止将运行时值注入构造函数in the first place。尝试添加一个Initialize 方法来传递运行时数据。还要防止使用factories to resolve dependencies
  • @Steven,感谢您提供如此有用的答案。

标签: c# dependency-injection inversion-of-control ninject


【解决方案1】:

我想解决这个问题最干净的方法是创建一个工厂:

interface IForm1Factory
{
    Form1 Create(int valueToEdit);
}

class Form1Factory
{
    public readonly ILogger _processRepository;
    public readonly Icopy _copy;

    public Form1Factory(ILogger logger, ICopy copy)
    {
        this._processRepository = logger;
        this._copy = copy;
    }

    public Form1 Create(int valueToEdit)
    {
        return new Form1(valueToEdit, _processRepository, _copy);
    }
}

还有一个扩展 (Ninject.Extensions.Factory) 允许您基于接口自动生成工厂,例如 Form1Factory。如果您使用该扩展名,则使用 Bind&lt;IForm1Factory&gt;().ToFactory() 声明。

【讨论】:

    【解决方案2】:
    using Ninject;
    using Ninject.Modules;
    using Ninject.Parameters;  
    //Add new class  
    public class CompositionRoot
    {
        public static IKernel _ninjectKernel;
        public static void Wire(INinjectModule module)
        {
            _ninjectKernel = new StandardKernel(module);
        }
        public static T Resolve<T>()
        {
            return _ninjectKernel.Get<T>();
        }
        public static T ResolveWithArgument<T>(ConstructorArgument argument)
        {
            return _ninjectKernel.Get<T>(argument);
        }
    }
    
    //Ninject bindings
    public class Bindings : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogger>().To<LogToDB>();
            Bind<ICopy>().To<CopyToFolder>();            
        }
    }
    
    //WinForm - Form1
    public partial class Form1 : Form
    {
        public readonly ILogger _processRepository;
        public readonly Icopy _copy;
        public readonly int ValueToEdit;
        public Form1(ILogger logger, ICopy copy, int valueToEdit)
        {
            this._processRepository = logger;
            this._copy = copy;
            this.ValueToEdit = valueToEdit;
            InitializeComponent();
        }
    }
    
    //main
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
       //Apply the binding rule first
       CompositionRoot.Wire(new Bindings());   
       //Then resolve your form dependencies this way using Ninject passing along the 
       constructor arguments. 
       CompositionRoot.ResolveWithArgument<Form1>(new ConstructorArgument("valueToEdit", 
       1)).ShowDialog();      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多