如何对CompositeCommand进行控制反转?

时间:2016-04-06 11:28:15

标签: c# mvvm inversion-of-control prism

我有以下ViewModel,我在构造函数中实例化CompositeCommand:

 public class ViewImportPreviewViewModel:BindableBase
    {
        private IEventAggregator eventAggregator;  //event aggregator to enable Studio button in different ViewModel

        private readonly IRegionManager regionManager; //region manager for navigation to the main menu

        public CompositeCommand finalizeImportClick;//composite command to register multiple command for finalize import button click


        public ViewImportPreviewViewModel(IRegionManager regionManager, IEventAggregator eventAggregator, CompositeCommand finalizeImportClick) //constructor
        {
            this.eventAggregator = eventAggregator;
            this.regionManager = regionManager;

            this.finalizeImportClick = finalizeImportClick;
            finalizeImportClick.RegisterCommand(new DelegateCommand<string>(NavigateToMain)); //register a delegate command for finalize import button click


        }


        //subscriber method to the firs delegate command registered with finalize button click
        private void NavigateToMain(string argument) 
        {
            //it enables the studio button after import and sends it to the main menu view XAML
            eventAggregator.GetEvent<ButtonEnableEvent>().Publish("ImportDone");

            //it navigates to the main menu after import
            regionManager.RequestNavigate("ScreenNavigationRegion", argument); 

            //publish an event for the main buttons viewmodel and then over there try to fade in main buttons
            eventAggregator.GetEvent<FadeinButtonsEvent>().Publish("ImportDone");
        }


    }

现在我想进行控制反转,并在类外部实例化CompositeCommand,然后通过Unity Container注入它,如下所示:

  CompositeCommand myCommand = new CompositeCommand();
  container.RegisterInstance<CompositeCommand>(myCommand);

然后在模块初始化时,我这样做:

NavigateToMain(string argument)

虽然命令已注册,但我没有收到任何错误,但RegisterCommand没有被调用。

我尝试注册类型,但CompositeCommand继承了ICommand接口,该接口不包含/[^\u0000-\u024F\u1E00-\u1EFF\u2C60-\u2C7F\uA720-\uA7FF]/g方法的定义。

1 个答案:

答案 0 :(得分:2)

实际上,CompositeCommands是单例/静态非常常见,因为多个松散耦合的模块将注册相同的CompositeCommand。这是标准的,也是预期的。

当然,您希望这样做以保持ViewModel的可测试性。您希望通过ctor知道您的依赖项。您不希望在VM中调用静态方法。

您要做的是创建一个自定义界面,如IApplicationCommands,并为您要公开的每个CompositeCommand提供属性,然后确保将该界面注册到您的容器。我还建议提供一个静态版本,以便您可以将按钮绑定到compositeCommands而无需引用绑定,这非常好。

所以也许是这样的:

    //Create an interface to abstract away the implementation of the static GlobalCommands class
public interface IGlobalCommands
{
    CompositeCommand SaveAllCommand { get; }
}

public static class GlobalCommands
{
    public static CompositeCommand SaveAllCommand = new CompositeCommand();
}

//Create a facade around the static GlobalCommands class
public class GloablCommandsFacade : IGlobalCommands
{
    public CompositeCommand SaveAllCommand
    {
        get { return GlobalCommands.SaveAllCommand; }
    }
}

并注册如下:

//register our global commands facade with the container as the IGlobalCommands interface so that we can ask for this service in our VM constructors
        // and remove the call to a static class in our VM.  This keeps us testable.
        Container.RegisterType<IGlobalCommands, GloablCommandsFacade>();