我在WPF应用程序中一起使用Caliburn Micro和Ninject。我正在使用Ninject.Extensions.Interception
来拦截和记录对我的ViewModel的调用,但这会阻止Caliburn找到ViewModel的视图,因为Caliburn正在传递截获的viewModel(代理),它具有不同的命名空间和名称。
例如,而不是得到:
MyApp.ViewModels.OrdersViewModel
它正在获得:
Castle.Proxies.IOrdersProxy
为了使事情进一步复杂化,ViewModel和Views位于不同的程序集中,因此不能假设名称空间。
由于我需要在运行时询问代理,我需要一种以编程方式挂钩到View解析的方法,而不是通过添加字符串映射。我认为没有办法做到这一点 - 是否可以使用Calliburn Micro?
答案 0 :(得分:1)
好的,我明白了。我没有打击映射,而是在WindowManager中展开代理:
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);
}