gpt4 book ai didi

mvvm - Prism 7 - 将 IContainer 对象注入(inject) View 模型

转载 作者:行者123 更新时间:2023-12-01 23:27:46 27 4
gpt4 key购买 nike

我最近有机会创建一个新的基于 Prism 的应用程序。我使用 6.3 版本已经有一段时间了,但看到 prism 7 已经退出预发布版,想试一试。我使用 Prism 模板包创建了一个新的 prism 应用程序,并且开箱即用。我像通常在 6.3 中所做的那样更新了 View 模型以传入容器,因此我可以解析一些稍后会向 View 提供信息的对象,在 6.3 中我将执行以下操作:

public MainWindowViewModel(IRegionManager aRegionManager,
IUnityContainer aUnityContainer) : base()
现在在 7.1.0.431 中,我尝试做同样的事情,但更新了接口(interface)以考虑新的 IOC 抽象。
public MainWindowViewModel(IRegionManager aRegionManager,
IContainerProvider aContainerProvider,
IContainerRegistry aContainerRegistry) : base()
这会从 IContainerX 参数的 ViewModelLocator.AutoWireViewModel 生成一个异常。
System.Exception {Unity.Exceptions.ResolutionFailedException}

{"Resolution of the dependency failed, type = 'Sample.ViewModels.MainWindowViewModel', name = '(none)'.\nException occurred while: while resolving.\nException is: InvalidOperationException - The current type, Prism.Ioc.IContainerProvider, is an interface and cannot be constructed. Are you missing a type
这就像我缺少一个引用,但是我将该类型传递到应用程序的 RegisterTypes 调用中,因此应该找到所有引用。我对新的 7.X 版本做错了吗?
编辑:每@mnistic
下面是模板包中提供的 App.xaml.cs 中的代码,其中传入了 IContainerRegistry。
  protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//containerRegistry is a valid instance here
}
更新 :
再深入一点,传递给 RegisterTypes 的 IContainerRegistry 列出了调用该方法时可用的所有类型/接口(interface)。它注册了一个 IUnityContainer 实例。当我创建项目时,我为 IOC 选择了 Unity,但我可能错误地认为 IContainerRegistry 将客户端隐藏在实际实现中。如果我更新 ViewModel 构造函数以接收 IUnityContainer 的对象,它会正确解析。
public MainWindowViewModel(IRegionManager aRegionManager,
IUnityContainer aContainerProvider) : base()
这是期望的行为吗?

最佳答案

不要这样做。您不想将容器放在解析根目录之外,测试起来很糟糕,隐藏了其他明显的依赖关系并且根本没有任何好处。
如果您需要服务,请直接注入(inject)它们。如需工厂,请注Func<IProduct>IHandcraftedFactory .如果您需要实现 ISomething 的所有已注册类型, 注入(inject) ISomething[]IEnumerable<ISomething> .
带有产品的示例(复杂)工厂:

public interface IFactory
{
IProduct CreateProduct( int someParameter );
}

internal class DeviceFactory : IFactory
{
public DeviceFactory( IService service )
{
_service = service;
}

public IProduct CreateProduct( int someParameter ) => new Device( someParameter, _someService );

private readonly IService _service;
private class Device : IProduct
{
public Device( int someParameter, IService aDependency )
{
// ...
}
}
}
如果 Device没有 someParameter , 你会跳过 IFactoryDeviceFactory只需注入(inject) Func<IProduct> ... Unity 会注意每个 Device收到它的 IService然后。
请记住 - 容器是为了简化事情:它解决依赖关系并创建实例并管理单例。但是如果你没有容器,一切仍然可以正常工作,就像你的单元测试一样。您只需要手动创建所有依赖项。
回到手头的主题 - IContainerRegistry只是 IUnityContainer 周围的一个短命的薄包装(在您的情况下),因此注册码在使用不同容器的不同应用程序中看起来有些相似。 Prism 试图通过不注册 IContainerRegistry 将您推向正确的方向(见上文)。这样您就可以在应该使用它的地方(在模块初始化期间)使用它,并防止您在其他地方使用它(通过使其无法注入(inject))。

关于mvvm - Prism 7 - 将 IContainer 对象注入(inject) View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52898013/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com