c# - MVVM 结合多数据源
问题描述
我从不同的 Web API 收集数据(因为我想让用户选择他们想要使用的来源)。即使数据具有相同类型的信息,数据模型也是不同的。
例如,一个 API 发送了这个模型:
public partial class Data
{
[JsonProperty("code")]
public int Code{ get; set; }
[JsonProperty("type")]
public Info Type { get; set; }
[JsonProperty("person")]
public Info Person{ get; set; }
}
public partial class Info
{
[JsonProperty("elementid")]
public int ElementId { get; set; }
[JsonProperty("$", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
}
另一个 API 发送了这个:
public partial class Data
{
[JsonProperty("id")] // This is corresponding to Code for previous api, it is easy to change
public int Code { get; set; }
[JsonProperty("name")]
public string name { get; set; } // This one is Type.Name => type problem
[JsonProperty("person")] // This data exists in both models but this is not the same type
// (but i can merge Info class from the first model with the Member class)
public Member Person{ get; set; }
}
public partial class Member
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("activity")]
public string Activity { get; set; }
[JsonProperty("url", NullValueHandling = NullValueHandling.Ignore)]
public string PictureUrl { get; set; }
}
在此示例中,我可以为某些 API 创建虚拟属性以拥有一个独特的模型。
问题是数据模型比那些代码复杂得多,我使用了四个源(所以,四个模型也是)。
目前,我使用一个非常痛苦和肮脏的代码来实现我的目标(这里只是一个例子,很多行需要相同的结构,OnPropertyChanged
定义了四次!!!):
if (myGrid.DataContext.GetType() == typeof(Sources.SourceA) && mySourceA != null)
{
mySourceA.IsFileSaved = true;
}
else if (myGrid.DataContext.GetType() == typeof(Sources.SourceB) && mySourceB != null)
{
mySourceB.IsFileSaved = true;
}
else if (myGrid.DataContext.GetType() == typeof(Sources.SourceC) && mySourceC != null)
{
mySourceC.IsFileSaved = true;
}
else if (myGrid.DataContext.GetType() == typeof(Sources.SourceD) && mySourceD != null)
{
mySourceD.IsFileSaved = true;
}
当然,我想在这里获得的只是:
if (mySources != null) // I know what model is used for DataContext !
{
mySources.IsFileSaved = true;
}
我的问题很简单,因为答案可能(应该?)很复杂:):我怎样才能只使用一个具有多个来源的模型?(也许我在尝试合并所有模型时没有以正确的方式进行,但我已经尝试了很多方式)
当然,只使用一个来源是最简单的方法,但我不想这样做。
谢谢你的想法......和你的解决方案(我希望如此:))
解决方案
您可以做到这一点的一种方法是使用策略模式。创建一个ISource
接口,如下所示:
namespace StrategySource
{
public interface ISource
{
bool IsFileSaved { get; set; }
// add any other common properties...
}
}
请注意,该ISource
接口包含IsFileSaved
所有源共有的属性。根据需要将任何其他常用成员添加到此接口。
然后让你的类实现这个接口,像这样:
namespace StrategySource
{
class SourceA : ISource
{
private bool isFileSaved;
// replace with your own custom implementation
public bool IsFileSaved
{
get { return isFileSaved; }
set { isFileSaved = value; }
}
}
class SourceB : ISource
{
private bool isFileSaved;
// replace with your own custom implementation
public bool IsFileSaved
{
get { return isFileSaved; }
set { isFileSaved = value; }
}
}
// other sources ...
}
每个SourceN
类都实现ISource
. 那是一份合同——由于这份合同,你知道他们也IsFileSaved
有财产。
您可以拥有任意数量的SourceN
类来实现ISource
。这为您提供了面向未来的可扩展性。
这使您可以一次性编写代码,如下所示:
using System.Collections.Generic;
namespace StrategySource
{
class Program
{
static void Main(string[] args)
{
List<ISource> sources = GetSources();
foreach (var source in sources)
if (source != null)
source.IsFileSaved = true;
}
static List<ISource> GetSources()
{
return new List<ISource>
{
new SourceA(),
new SourceB()
// and so on
};
}
}
}
我使用 将GetSources
这些中的每一个都拉到一个集合中,听起来您已经有了执行此操作的代码。
这里的重点是,因为每个SourceN
类都实现了相同的接口,所以您可以编写一个以相同方式对所有类进行操作的算法。您可能听说过这称为接口多态性。
推荐阅读
- php - 执行 PhantomJs 过程时出错 - 文件不存在或不可执行
- php - 使用 php 中的单选按钮重定向到另一个页面
- node.js - ArcGIS JS API 4.7 和 NPM 错误
- ssl - 让我们加密 ssl 证书在 TLS 握手中发送两次
- php - JMS 序列化过程中使用什么方法?
- jquery - ajax返回404但显示json?
- javascript - 用备用图片替换损坏的 img
- python - Scipy rv_continuous 错误地从分布中生成样本
- php - 有没有办法限制供应商的包版本要求
- python - 为什么 (3.3==np.asarray([3.3])) 等于 [True] 而不是 False?