我在WPF应用程序中一起使用Caliburn Micro和Ninject。我正在使用Ninject.Extensions.Interception
来拦截和记录对我的 ViewModel 的调用,但这会阻止 Caliburn 找到 ViewModel 的视图,因为 Caliburn 正在被移交截获的视图模型(代理),该模型具有不同的命名空间和名称。
例如,而不是获得:
MyApp.ViewModels.OrdersViewModel
它正在得到:
Castle.Proxies.IOrdersProxy
更复杂的是,视图模型和视图位于不同的程序集中,因此不能假定命名空间。
由于我需要在运行时询问代理,因此我需要一种方法以编程方式挂钩到 View 解析,而不是通过添加字符串映射。我看不出有任何方法可以做到这一点 - 卡利本微型可以吗?
好的,我明白了。我没有与映射作斗争,而是在窗口管理器中解开代理:
using System;
using System.Collections.Generic;
using Caliburn.Micro;
using Castle.DynamicProxy;
namespace CAM.Utility
{
public class WindowManagerEx : WindowManager, IWindowManagerEx
{
private readonly List<object> _trayIcons;
public WindowManagerEx()
{
_trayIcons = new List<object>();
}
public override bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
rootModel = rootModel.UnwrapProxy();
return base.ShowDialog(rootModel, context, settings);
}
public override void ShowWindow(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
rootModel = rootModel.UnwrapProxy();
base.ShowWindow(rootModel, context, settings);
}
public override void ShowPopup(object rootModel, object context = null, IDictionary<string, object> settings = null)
{
rootModel = rootModel.UnwrapProxy();
base.ShowPopup(rootModel, context, settings);
}
public bool? ShowDialog<TViewModel>(object context = null, IDictionary<string, object> settings = null)
{
var viewModelInstance = IoC.Get<TViewModel>();
return ShowDialog(viewModelInstance, context, settings);
}
public void ShowWindow<TViewModel>(object context = null, IDictionary<string, object> settings = null)
{
var viewModelInstance = IoC.Get<TViewModel>();
ShowWindow(viewModelInstance, context, settings);
}
public void ShowPopup<TViewModel>(object context = null, IDictionary<string, object> settings = null)
{
var viewModelInstance = IoC.Get<TViewModel>();
ShowPopup(viewModelInstance, context, settings);
}
public void ShowTrayIcon<TViewModel>(object context = null)
{
var viewModelInstance = IoC.Get<TViewModel>();
_trayIcons.Add(viewModelInstance);
}
public void Dispose()
{
foreach (var trayIcon in _trayIcons)
{
var disposable = trayIcon as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
}
public static class CastleProxyExtensions
{
public static object UnwrapProxy(this object target)
{
var proxy = target as IProxyTargetAccessor;
if (proxy != null)
{
dynamic dynamicProxy = proxy;
dynamic interceptors = dynamicProxy.__interceptors;
dynamic interceptor = interceptors[0];
target = interceptor.Instance;
}
return target;
}
}
}
另外,如果您想知道IWindowManagerEx是什么:
public interface IWindowManagerEx : IWindowManager, IDisposable
{
bool? ShowDialog<TViewModel>(object context = null, IDictionary<string, object> settings = null);
void ShowWindow<TViewModel>(object context = null, IDictionary<string, object> settings = null);
void ShowPopup<TViewModel>(object context = null, IDictionary<string, object> settings = null);
void ShowTrayIcon<TViewModel>(object context = null);
}