【发布时间】:2011-01-15 10:41:01
【问题描述】:
我的 WPF 项目将这样组织:
Screens
Group1
Screen1
View.xaml
ViewModel.cs
Group2
Screen2
View.xaml
ViewModel.cs
为了从Screen2 中显示Screen1,我将使用如下内容:ScreenManager.Show("Group1.Screen1") 这在Screens.Group1.Screen1 命名空间中查找(使用反射)View 和 ViewModel 并实例化它们。
如何在不耦合Screen1 和Screen2 的情况下消除魔术字符串(我不希望Screen2 中的类使用Screen1 命名空间)。我也想要某种屏幕发现(自动完成/智能感知)
或者也许通过某种方式(自动测试)来验证对ScreenManager.Show 的所有调用都是有效的。
更新: 我想出了这个:
public class ScreenNames
{
public Group1Screens Group1;
public class Group1Screens
{
public ScreenName Screen1;
}
}
public sealed class ScreenName
{
private ScreenName() { }
}
public class ScreenManager : IScreenManager
{
public void Show(Expression<Func<ScreenNames, ScreenName>> x) {}
}
用法:
screenManager.Show(x=>x.Group1.Screen1);
不理想,但我认为违反 DRY 仍然比魔术字符串好。而且我可以自动测试(通过反射)所有调用都是有效的。
【问题讨论】:
-
为什么 Screen2 需要知道 Screen1?屏幕管理器不存在于每个屏幕之外吗?通过 Intellisense,您是说在开发过程中,当您开始键入 ScreenManager.Show() 时,您希望每个屏幕的名称都出现在下拉列表中?屏幕列表是静态的还是动态的(在运行时加载)?
-
最终我会传递一个参数; ScreenManager 将是 ViewModel 的一个属性;对于智能感知,我认为静态列表是必须的:/ 我想我可以有这样的东西:ScreenManager.Show(x=>x.Group1.Screen1)
-
ScreenManager.Show(x=>x.Group1.Screen1) 之类的用法意味着我必须保留和维护单独的屏幕列表,但我认为如果我想要智能感知,没有其他办法
-
酷,我喜欢用 lambda 表达式获取 Intellisense 的方法。
标签: c# wpf architecture mvvm magic-string