全称:Inversion of Control,控制反转
场景:A页面需要调用B/C页面等,防止直接在VM中新建别的页面实例,使用IOC设计架构;
创建Service,在Service中实现页面的实例创建和定义页面输入输出参数。
在MainView中注册A、B、C页面的Service。
A需要调用B时,调用B的Service。
此架构思路可以在MVVM基础上,减少不同模块的耦合。
可以所有模块的页面都注册服务。让VM之间不存在互相调用
手动实现
IOC类
public static class IoC
{
private static readonly Dictionary<Type, object> MAP;
static IoC()
{
MAP = new Dictionary<Type, object>();
}
public static void Register<T>(T instance)
{
MAP[typeof(T)] = instance;
}
public static T Provide<T>()
{
if (MAP.TryGetValue(typeof(T), out object obj) && obj is T t)
{
return t;
}
throw new Exception("No registered service of type " + typeof(T));
}
}
IView接口
public interface IView
{
/// <summary>
/// Close the view with the given result
/// </summary>
void CloseDialog(bool result);
}
页面B实现IView
public partial class ChildValuePopup : Window, IView
{
public ChildValueEditPopupViewModel ViewModel => (ChildValueEditPopupViewModel)this.DataContext;
public ChildValuePopup()
{
InitializeComponent();
DataContext = new ChildValueEditPopupViewModel(this);
}
public void CloseDialog(bool result)
{
this.DialogResult = result;
this.Close();
}
}
IViewBService页面B的Service接口
public interface IChildValueEditPopupService
{
//打开B页面方法,及其输入输出参数
Task<ChildValueEditPopupResult> ChildValueEditPopupOpenAsync(GirdDataModel data);
ChildValueEditPopupResult ChildValueEditPopupOpen(GirdDataModel data);
}
//输出参数类定义
//IsSuccess是否成功打开B页面
public class ChildValueEditPopupResult : ObservableObject
{
public bool IsSuccess { get; set; }
private object _setValue;
public string code { get; set; }
public object setValue { get=>_setValue; set=>OnPropertyChanged(ref _setValue,value); }
}
ViewBService页面B的Service实现
internal class ChildValueEditPopupService : IChildValueEditPopupService
{
public ChildValueEditPopupResult ChildValueEditPopupOpen(GirdDataModel data)
{
var popup = new ChildValuePopup();
popup.ViewModel.Code = data.code;
popup.ViewModel.ChildValues = Copy.DeepCopy( data.childValues);
popup.ViewModel.SetValue = data.setValue;
bool result = popup.ShowDialog() == true;
if (!result) {
return new ChildValueEditPopupResult() { IsSuccess = false};
}
return new ChildValueEditPopupResult()
{
IsSuccess = true,
code = popup.ViewModel.Code,
setValue = popup.ViewModel.SetValue,
};
}
public async Task<ChildValueEditPopupResult> ChildValueEditPopupOpenAsync(GirdDataModel data) {
return await Application.Current.Dispatcher.InvokeAsync(() => {
return ChildValueEditPopupOpen(data);
});
}
}
注册服务,全局页面MainView
public MainWindow()
{
InitializeComponent();
IoC.Register<IChildValueEditPopupService>(new ChildValueEditPopupService());
}
使用服务,页面A打开页面B
private void ChildValueEditPopupOpen(GirdDataModel data) {
IChildValueEditPopupService service = IoC.Provide<IChildValueEditPopupService>();
ChildValueEditPopupResult res = service.ChildValueEditPopupOpen(data);
if (res.IsSuccess) {
data.setValue = res.setValue;
}
}