1

I am creating a factory using interface as

public interface ICommandFactory
{
  ICommand CreateCommand(Action executeMethod);
  ICommand CreateCommand(Action executeMethod, Func<bool> canExecuteMethod);
}

public class DelegateCommand : DelegateCommand<object>
{
    public DelegateCommand(Action executeMethod)
        : base(o => executeMethod())
    {
    }

    public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod)
        : base(o => executeMethod(), o => canExecuteMethod())
    {
    }
}

public class DelegateCommand<T> : ICommand
{
    public DelegateCommand(Action<T> executeMethod)
        : this(executeMethod, null)
    {
    }

    public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
    {

    }
}

My Ninject binding is done using

_kernel.Bind(x => x.FromAssembliesMatching("xyz*")
                        .SelectAllClasses()                                
                        .BindAllInterfaces());

_kernel.Bind(x => x.FromAssembliesMatching("xyz*")
                        .SelectAllInterfaces()
                        .EndingWith("Factory")
                        .BindToFactory()
                        .Configure(c => c.InSingletonScope()));

When I call in my view model it is causing activation exception although I tried with Named binding.

public class MyViewModel
{
  public ICommand SaveCommand {get; private set;}

  public MyViewModel(ICommandFactory commandFactory)
  {
    SaveCommand = commandFactory.CreateCommand(Save, () => SelectedTask != null);
  }
}

The exception is caused in DelegateCommand's constructor on 'o => canExecuteMethod()' line. Also, I cannot use constructor param passing in Ninject as my logic for canExecute is in my ViewModel. Any solution or fix is accepted.

1 Answers1

0

Your issue is caused by Ninject.Extensions.Factory creating a binding for Func<>'s.

When you are using said extension, ninject is configured so that you can inject a Func<> as a factory. Func<bool> is basically bound like

kernel.Bind<Func<bool>>().ToMethod(() => 
{
    return (Func<bool>) = () => kernel.Get<bool>();
}

Now this is paired with the fact, that ninject will use the public constructor with the most parameters it can resolve. That means, even if you use CreateCommand(Action executeMethod);, ninject will use the public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod) constructor and inject a "bool factory" as the Func<bool> parameter.

Workarounds

Wrapping the Func in an interface

There's many ways to do this, let me show you one:

public class Wrapper<T>
{
    public T Wrapped { get; set; }
}

and adapt the factory to:

public interface ICommandFactory
{
  ICommand CreateCommand(Action executeMethod, Wrapper<Func<bool>> canExecuteMethod);
}

and the delegate command constructor:

public class DelegateCommand : ICommand
{
    public DelegateCommand(Action<T> executeMethod, Wrapper<Func<bool>> canExecuteMethod)
    {
    }
}

Removing the factory extensions Func bindings

See Stop Ninject from binding Func<T, T, bool> automatically

Community
  • 1
  • 1
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68