用MVVM和Prism理解统一和依赖注入

时间:2015-04-20 06:07:34

标签: c# wpf mvvm dependency-injection unity-container

我开始使用Microsoft的Prism框架和Unity作为WPF应用程序,主要是为了自学一些新概念。

我一直在努力理解依赖注入以及如何将Unity与我的视图模型一起使用,但我对自己正在做的事情没有足够的把握,甚至不知道我做错了什么。

因此,我将介绍我所处的情景,并希望有人能帮助我了解我出错的地方。

让我们考虑一个EventAggregator场景,ModuleA发布和ModuleB订阅。在我的ModuleA MainWindowViewModel中,我会有一个像这样的类构造函数:

private IEventAggregator _eventAggregator;
public MainWindowViewModel(IEventAggregator eventAggregator) {
    _eventAggregator = eventAggregator;
    ...
}

现在,当我注册ModuleA MainWindowView时,我会做这样的事情:

public class ModuleA {
    private readonly IRegionManager _regionManager;
    public ModuleA(IRegionManager regionManager) {
        _regionManager = regionManager;
    }

    public void Initialize() {
        _regionManager.RegisterViewWithRegion("SomeRegion", typeof(MainWindowView));
    }
}

然后,在我的项目Bootstrapper.cs中,我会创建我的ModuleCatalog

public class Bootstrapper {
    ...
    protected override void ConfigureModuleCatalog() {
        base.ConfigureModuleCatalog();
        ModuleCatalog moduleCatalog = (ModuleCatalog)this.ModuleCatalog;

        moduleCatalog.AddModule(typeof(ModuleA.ModuleA));
        ...
    }
}

现在,我可以使用ServiceLocator在我的ViewModel中实例化我的eventAggregator,但我正在尝试通过依赖注入,使用IUnityContainer注册我的ViewModel然后注入我认为必要。此外,我一直看到我实际上应该使用ViewModel的接口(即IMainWindowViewModel)来分离问题。

有人能指出我可以清除我所遇到的明显混乱的资源吗?我已经阅读过MSDN的Prism快速入门,包括高级MVVM场景,但我不明白如何将指令置于语境中。

1 个答案:

答案 0 :(得分:0)

  1.   

    现在,我可以使用ServiceLocatoreventAggregator中实例化我的ViewModel,但我正在尝试通过依赖注入执行此操作,将ViewModel注册到IUnityContainer View然后根据需要注入ViewModel

    上面提到了两种不同的机制:

      

    服务定位器与依赖注入

         

    基本选择是服务定位器和依赖注入之间。第一点是两个实现都提供了天真示例中缺少的基本解耦 - 在这两种情况下,应用程序代码都独立于服务接口的具体实现。这两种模式之间的重要区别在于如何为应用程序类提供该实现。使用服务定位器,应用程序类通过发送给定位器的消息明确地请求它。使用注入没有明确的请求,服务出现在应用程序类中 - 因此控制反转。

         

    - Inversion of Control Containers and the Dependency Injection pattern, Martin Fowler

    结论。必须有一个架构决策:“使用哪种机制?”。

  2.   

    此外,我一直看到我应该使用我的IMainWindowViewModel(即/** * @param filePath * @param fs * @return list of absolute file path present in given path * @throws FileNotFoundException * @throws IOException */ public static List<String> getAllFilePath(Path filePath, FileSystem fs) throws FileNotFoundException, IOException { List<String> fileList = new ArrayList<String>(); FileStatus[] fileStatus = fs.listStatus(filePath); for (FileStatus fileStat : fileStatus) { if (fileStat.isDirectory()) { fileList.addAll(getAllFilePath(fileStat.getPath(), fs)); } else { fileList.add(fileStat.getPath().toString()); } } return fileList; } )的界面来区分问题。

    这就是依赖倒置原则的应用方式。

      

    依赖性倒置原则:

         

    一个。高级模块不应该依赖于低级模块。两者都应该取决于抽象。

         

    B中。抽象不应该依赖于细节。细节应取决于抽象。

         

    - The Dependency Inversion Principle, Robert C. Martin, 1996

    “详细信息”是具体类型,“抽象”是接口。

  3. 有关详细信息,请参阅引用的参考文献。