Как мне предоставить дополнительные параметры с помощью Ninject? - PullRequest
1 голос
/ 03 апреля 2019

Мне нужно автоматически разрешить зависимости моей формы 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 Нет соответствующих привязок, и тип не является самосвязываемым.

Как я могу автоматически разрешить зависимости формы, а также передать целочисленное значение?На самом деле, я использовал ту же форму для добавления и редактирования, поэтому при редактировании это значение редактирования должно быть установлено.

Ответы [ 2 ]

3 голосов
/ 03 апреля 2019

Полагаю, самый простой способ решить эту проблему - создать фабрику:

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 голосов
/ 08 апреля 2019
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();      
}
...