如何使用Ninject提供额外参数?

问题描述 投票:1回答:2

我需要自动解析我的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没有匹配的绑定可用,并且该类型不可自我绑定。

如何自动解析表单依赖项并且还能够传递整数值?实际上,我使用相同的表单进行添加和编辑,因此在编辑时,应该设置此编辑值。

c# dependency-injection inversion-of-control ninject
2个回答
3
投票

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

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<IForm1Factory>().ToFactory()声明。


0
投票
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();      
}
© www.soinside.com 2019 - 2024. All rights reserved.