统一初始化分层树视图模型
Initialize hierarchical tree viewmodels with unity
我正在调查我们的应用程序中使用 Prism 的更改。目前我正在为层次结构的初始化而苦苦挣扎。
基本上我有一个基础 class 其他 class 继承,简化如下:
public class NodeViewModel : INodeViewModel
{
Node Node { get; private set; }
public ObservableCollection<INodeViewModel> ChildNodeViewModels { get; private set; }
public NodeViewModel(IUnityContainer container, Node node)
{
Node = node;
ChildNodeViewModels = new ObservableCollection<INodeViewModel>();
foreach (Node childNode in Node.ChildNodes)
{
// Some initialization code
}
}
}
到目前为止我还没有使用容器,所以我们只有 Node 参数。每个继承的 class 都有一个属性,我们将其用于模型到视图模型的映射。
[ModelToViewModelMapping(typeof(InheritedNode ))]
public class InheritedViewModel: NodeViewModel
{
public InheritedViewModel(InheritedNode inheritedNode)
: base(inheritedNode)
{
}
}
然后我有一个这样的初始化行:
ChildNodeViewModels.Add((INodeViewModel)System.Activator.CreateInstance(ModelToViewModelMappingDictionary.GetMappedViewModelType(childNode.GetType()), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, new object[] { childNode }, null));
我的问题是双重的。
- 我不知道我用属性的老把戏是否是映射的通用解决方案。我想不是,但它以一种简单的方式将事情放在一起并易于管理。我不确定 viewmodellocator 是否是一个好的解决方案,我对它是全新的,我还没有尝试过。
- 如何初始化。 Resolve 方法使用我可以通过某种方式解析的类型(我的属性解决方案、viewmellocator 等),但 Unity 的
ParameterOverride
需要 string parameterName
。如上面的代码所示,由于 parameterName 不是常量而失败,每个继承的 class 都有自己的 parameterName.
提前致谢!
- 你的把戏很常见。比较常见的是:
InheritedViewModel < InheritedNode >
其中还有:
NodeViewModel
当然还有:
INodeViewModel
- Prism 的部分功能是从容器中获取您需要的实例,如下所示:
Container(或者你怎么称呼它).GetInstance(或者不管它叫什么)< INodeViewModel < InheritedNode >>()
您需要先在容器 InheritedViewModel 中注册 INodeViewModel 才能正常工作
广告 1:
我喜欢您当前的选择,因为您可以避免以这种方式创建大量工厂。
广告 2:
unity你要提供参数名,所以你要手动反映构造函数,找到你要覆盖的参数名。然后你就可以通过unity解析你的view model,传入model。 但有一个问题!当使用参数覆盖解析时,您覆盖任何恰好与覆盖中的参数名称匹配的参数,在层次结构,无论是什么类型。在最好的情况下,类型不匹配,你会得到一个异常,在最坏的情况下,一个错误的依赖被注入,静默。祝调试愉快...
推荐:
坚持您当前生成视图模型的方式,并在构造对象时注入依赖项。这也有缺点,因为您不能使用构造函数注入并且您需要对容器的引用,但我更喜欢那些而不是相当不可预测的参数覆盖。
var viewModel = Activator.CreateInstance(...);
_container.BuildUp( viewModel );
与
internal class MyChildViewModel
{
[Dependency]
public ISomeService MyDependency { get; set; }
}
我正在调查我们的应用程序中使用 Prism 的更改。目前我正在为层次结构的初始化而苦苦挣扎。
基本上我有一个基础 class 其他 class 继承,简化如下:
public class NodeViewModel : INodeViewModel
{
Node Node { get; private set; }
public ObservableCollection<INodeViewModel> ChildNodeViewModels { get; private set; }
public NodeViewModel(IUnityContainer container, Node node)
{
Node = node;
ChildNodeViewModels = new ObservableCollection<INodeViewModel>();
foreach (Node childNode in Node.ChildNodes)
{
// Some initialization code
}
}
}
到目前为止我还没有使用容器,所以我们只有 Node 参数。每个继承的 class 都有一个属性,我们将其用于模型到视图模型的映射。
[ModelToViewModelMapping(typeof(InheritedNode ))]
public class InheritedViewModel: NodeViewModel
{
public InheritedViewModel(InheritedNode inheritedNode)
: base(inheritedNode)
{
}
}
然后我有一个这样的初始化行:
ChildNodeViewModels.Add((INodeViewModel)System.Activator.CreateInstance(ModelToViewModelMappingDictionary.GetMappedViewModelType(childNode.GetType()), System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance, null, new object[] { childNode }, null));
我的问题是双重的。
- 我不知道我用属性的老把戏是否是映射的通用解决方案。我想不是,但它以一种简单的方式将事情放在一起并易于管理。我不确定 viewmodellocator 是否是一个好的解决方案,我对它是全新的,我还没有尝试过。
- 如何初始化。 Resolve 方法使用我可以通过某种方式解析的类型(我的属性解决方案、viewmellocator 等),但 Unity 的
ParameterOverride
需要string parameterName
。如上面的代码所示,由于 parameterName 不是常量而失败,每个继承的 class 都有自己的 parameterName.
提前致谢!
- 你的把戏很常见。比较常见的是:
InheritedViewModel < InheritedNode >
其中还有:
NodeViewModel
当然还有:
INodeViewModel
- Prism 的部分功能是从容器中获取您需要的实例,如下所示:
Container(或者你怎么称呼它).GetInstance(或者不管它叫什么)< INodeViewModel < InheritedNode >>()
您需要先在容器 InheritedViewModel
广告 1:
我喜欢您当前的选择,因为您可以避免以这种方式创建大量工厂。
广告 2:
unity你要提供参数名,所以你要手动反映构造函数,找到你要覆盖的参数名。然后你就可以通过unity解析你的view model,传入model。 但有一个问题!当使用参数覆盖解析时,您覆盖任何恰好与覆盖中的参数名称匹配的参数,在层次结构,无论是什么类型。在最好的情况下,类型不匹配,你会得到一个异常,在最坏的情况下,一个错误的依赖被注入,静默。祝调试愉快...
推荐:
坚持您当前生成视图模型的方式,并在构造对象时注入依赖项。这也有缺点,因为您不能使用构造函数注入并且您需要对容器的引用,但我更喜欢那些而不是相当不可预测的参数覆盖。
var viewModel = Activator.CreateInstance(...);
_container.BuildUp( viewModel );
与
internal class MyChildViewModel
{
[Dependency]
public ISomeService MyDependency { get; set; }
}