将ViewModel添加到截取类型的View类型映射

时间:2015-01-16 18:11:34

标签: c# caliburn.micro ninject-interception

我在WPF应用程序中一起使用Caliburn Micro和Ninject。我正在使用Ninject.Extensions.Interception来拦截和记录对我的ViewModel的调用,但这会阻止Caliburn找到ViewModel的视图,因为Caliburn正在传递截获的viewModel(代理),它具有不同的命名空间和名称。

例如,而不是得到:

MyApp.ViewModels.OrdersViewModel

它正在获得:

Castle.Proxies.IOrdersProxy

为了使事情进一步复杂化,ViewModel和Views位于不同的程序集中,因此不能假设名称空间。

由于我需要在运行时询问代理,我需要一种以编程方式挂钩到View解析的方法,而不是通过添加字符串映射。我认为没有办法做到这一点 - 是否可以使用Calliburn Micro?

1 个答案:

答案 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);
}