![](/img/trans.png)
[英]Prism5 + Unity, how to raise popup after shell and all modules loaded
[英]Initialize Shell with ViewModel after all modules loaded in Prism 6
我的Shell / MainWindow的ViewModel(通過AutoWireViewModel="True"
)請求使用ConfigurationModuleCatalog在啟動時加載到模塊中的依賴項。
因為Shell在模塊之前被初始化,所以DI容器顯然無法解析它,因此應用程序崩潰了。
public class MainWindowViewModel : BindableBase
{
// Cannot resolve IService
public MainWindowViewModel(IService service)
{
}
}
我已經嘗試過這篇文章的兩種方法,但兩種方法都沒有用。
我這樣試過:
public interface IShellService
{
int NumberOfLoadedModules { get; }
void FlagModuleAsLoaded();
}
public class ShellService : IShellService
{
private readonly IModuleCatalog _moduleCatalog;
public ShellService(IModuleCatalog moduleCatalog)
{
_moduleCatalog = moduleCatalog;
}
public int NumberOfLoadedModules { get; private set; }
public void FlagModuleAsLoaded()
{
NumberOfLoadedModules++;
if (NumberOfLoadedModules != _moduleCatalog.Modules.Count())
return;
InitializeShell();
}
private static void InitializeShell()
{
Application.Current.MainWindow.Show();
}
}
internal class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return null;
}
protected override void InitializeShell()
{
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterInstance<IShellService>(new ShellService(ModuleCatalog), new ContainerControlledLifetimeManager());
}
protected override IModuleCatalog CreateModuleCatalog()
{
return new ConfigurationModuleCatalog();
}
}
用法
public abstract class ModuleBase : IModule
{
private readonly IShellService _shellService;
protected ModuleBase(IShellService shellService)
{
_shellService = shellService;
}
public void Initialize()
{
InitializeInternal();
FlagAsLoaded();
}
public abstract void InitializeInternal();
public void FlagAsLoaded()
{
_shellService.FlagModuleAsLoaded();
}
}
public class FooModule : ModuleBase
{
IUnityContainer _container;
public MusicUIModule(IUnityContainer container, IShellService shellService) : base(shellService)
{
_container = container;
}
public override void InitializeInternal()
{
_container.RegisterType<IService, Service>();
}
}
它開始計算模塊,然后由於相同的原因應用程序崩潰。
如果上述方法不符合我的目的,那么該問題怎么解決?
謝謝!
我試圖實現Haukinger的建議並以這種方式做到這一點很好:
// Factory --------------------------------------------------------
public interface IDependencyFactory
{
IService GetService();
}
public class DependencyFactory : IDependencyFactory
{
private readonly IUnityContainer _container;
public DependencyFactory(IUnityContainer container)
{
_container = container;
}
public IService GetService()
{
return _container.Resolve<IService>();
}
}
// PubSubEvent ------------------------------------------------------
public class AllModulesLoaded : PubSubEvent
{
}
// Bootstrapper -----------------------------------------------------
internal class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
protected override void InitializeModules()
{
base.InitializeModules();
// Publishing event to tell subscribers that the modules are loaded
var eventAggregator = Container.Resolve<IEventAggregator>();
eventAggregator?.GetEvent<AllModulesLoaded>().Publish();
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
// ...
Container.RegisterType<IDependencyFactory, DependencyFactory>();
}
protected override IModuleCatalog CreateModuleCatalog()
{
return new ConfigurationModuleCatalog();
}
}
// ViewModel ---------------------------------------------------------
public class MainWindowViewModel : BindableBase
{
private IService _service;
private readonly IEventAggregator _eventAggregator;
private readonly IDependencyFactory _dependencyFactory;
public MainWindowViewModel(IEventAggregator eventAggregator, IDependencyFactory dependencyFactory)
{
_eventAggregator = eventAggregator;
_dependencyFactory = dependencyFactory;
_eventAggregator.GetEvent<AllModulesLoaded>().Subscribe(OnAllModulesLoaded);
}
private void OnAllModulesLoaded()
{
var service = _dependencyFactory.GetService();
if (service != null)
_service = service ;
_eventAggregator.GetEvent<AllModulesLoaded>().Unsubscribe(OnAllModulesLoaded);
}
}
我將shell隱藏在工廠/提供程序后面,然后在加載最后一個模塊時創建/獲取它。 shell的視圖模型訂閱了一個AllModulesLoaded
事件,當base.InitializeModules
返回時,它會從引導程序的InitializeModules
觸發,以通知依賴項可用。 或者工廠/提供者訂閱該事件,並且shell會輪詢它,具體取決於您希望如何使用依賴項。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.