我尝试使用基本的MVVM创建一个WPF音乐播放器,但是由于依赖性太多,我达到了一些限制,因此我选择了 Prism 以(希望)更好的方式构建我的应用程序模块。
我已经观看并阅读了很多关于Prism的内容,并创建了一些基本的和扩展的示例应用程序来获得更好的知识。 我唯一真正的问题是,由于它的依赖性,我不知道如何构造以及在何处实现应用程序的部分。
我的结构现在看起来像这样:
在App.Core.Music
中,我获得了与音乐内容相关的其他模块的所有接口和一些共享对象/枚举:
IMusicManager :
包含映射的播放方法和绑定道具,可访问的槽DI容器作为单例并且共享如下:
public class MusicModule : IModule
{
private readonly IUnityContainer _unityContainer;
public MusicModule(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Initialize()
{
var musicSettings = XmlHelper.Get<CurrentMusicSettings>(CurrentMusicSettings.FileName) ?? new CurrentMusicSettings();
var playlistSettings = XmlHelper.Get<PlaylistSettings>(PlaylistSettings.FileName) ?? new PlaylistSettings();
_unityContainer.RegisterInstance<ICurrentMusicSettings>(musicSettings, new ContainerControlledLifetimeManager());
_unityContainer.RegisterInstance<IPlaylistSettings>(playlistSettings, new ContainerControlledLifetimeManager());
_unityContainer.RegisterType<IMusicManager, MusicManager>(new ContainerControlledLifetimeManager());
// Getting the music manager by container because of its dependencies
var musicManager = ServiceLocator.Current.GetInstance<IMusicManager>();
musicManager.Load();
}
}
namespace App.Music.UI.ViewModels
{
public class PlayBarViewModel : BindableBase
{
private IMusicManager _musicManager;
public PlayBarViewModel(IMusicManager musicManager)
{
_musicManager = musicManager;
BackwardCommand = new DelegateCommand(MusicManager.GoBackward);
ForwardCommand = new DelegateCommand(MusicManager.GoForward);
}
// Bound like <Slider Value="{Binding MusicManager.CurrentTrackPosition}" />
public IMusicManager MusicManager
{
get { return _musicManager; }
set { SetProperty(ref _musicManager, value); }
}
// Command Properties...
}
}
IMusicEngine :播放的真实实例,包含在 IMusicManager
所以App.Music
模块中的接口实现和对象如PlaylistBase
,Playlist
,Track
和TrackBase
无法从外部访问模块。
这是否有意义,因为我需要在其他模块中使用ITrack“实例”,当我想创建一些时,我应该通过请求一些DI容器并操纵它们来获取它们吗?
在App.Core.Settings
中只有一些设置接口,如IConfigurationSettings : ISettings
,它们在主/ shell项目App中实现,因为它们在引导程序中是必需的。
由于XML序列化,需要App.Music.Settings
中实现的其他设置。
因此,所有与音乐相关的模块首先需要加载App.Music模块,我在App.config
中执行此操作:
<modules>
<module assemblyFile="Modules\App.Music.dll" moduleType="..." moduleName="MusicModule" startupLoaded="True" />
<module assemblyFile="Modules\App.Music.UI.dll" moduleType="..." moduleName="MusicUIModule" startupLoaded="True">
<dependencies>
<dependency moduleName="MusicModule" />
</dependencies>
</module>
</modules>
对于我上面的问题,我想问一下这是否可以,以及未来可操作/可扩展?我能做什么/我应该做得更好?
答案 0 :(得分:0)
因此,在App.Music模块中,接口实现和对象如PlaylistBase,Playlist,Track和TrackBase无法从模块外部访问。这是否有意义,因为我需要ITrack&#34;实例&#34;在其他模块中
完全没问题,e.g. in Prism documentation:
跨模块通信的另一种方法是通过共享服务。加载模块后,模块会将其服务添加到服务定位器。通常,通过公共接口类型从服务定位器注册和检索服务。这允许模块使用其他模块提供的服务,而无需对模块进行静态引用。服务实例在模块之间共享,因此您可以在模块之间共享数据和传递消息。
在Stock Trader参考实施(Stock Trader RI)中,Market模块提供了IMarketFeedService的实现。 Position模块通过使用shell应用程序的依赖注入容器来使用这些服务,该容器提供服务位置和解析。 IMarketFeedService旨在被其他模块使用,因此可以在StockTraderRI.Infrastructure通用程序集中找到,但此接口的具体实现不需要共享,因此它直接在Market模块中定义,可以是独立于其他模块更新。