【问题标题】:Castle Windsor Interceptor on Caliburn View ModelCaliburn 查看模型上的 Castle Windsor 拦截器
【发布时间】:2013-03-04 19:19:06
【问题描述】:

我想用 Castle Windsor Interceptor 创建自己的方面并应用于 View Model 类。

正如我所说,我使用 Caliburn MVVM 框架,在 DI 上我使用 Caste Windsor。一切正常。

例如我创建了简单的日志拦截器,这里是:

public class LoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.Write("Log: Method Called: " + invocation.Method.Name);
        invocation.Proceed();
    }
}

这是一个简单的 View Model 类 - 它是“标签项”:

public class TabViewModel : Screen, 
    ITabViewModel
{

}

当我使用 Fluent API 配置 IoC 时,我想在 View Model 类上应用这个拦截器。

       container.Register(Component
                    .For<LoggingInterceptor>()
                    .LifeStyle
                        .Singleton
                    .Named("LogAspect"));

        container.Register(Component
                    .For<ITabViewModel>()
                    .ImplementedBy<TabViewModel>()
                    .LifeStyle
                        .Transient
                    .Named("TabViewModel")
                    .Interceptors<LoggingInterceptor>());

当我尝试从 IoC 中选择视图模型时:

var tabItem = IoC.Get<ITabViewModel>();
ActivateItem(tabItem);

我收到了这条消息:

未找到 Castle.Proxies.ITabViewModelProxy 的默认视图。 搜索的视图包括:Castle.Proxies.IITabViewModelProxy Castle.Proxies.ITabViewModelProxys.IDefault Castle.Proxies.ITabViewModelProxys.Default

我也尝试过这种方式用于拦截器应用程序。

[Interceptor(typeof(LoggingInterceptor))]
public class TabViewModel : Screen, 
    ITabViewModel
{

}

好的,我知道 Caliburn 框架通过命名约定匹配 View 和 View Model。

当我尝试选择 ITabViewModel 的实现时,我得到了 ITabViewModelProxy,而对于 ITabViewModelProxy,我没有注册任何视图。

代理的目标是 TabViewModel 但我认为问题在于命名不匹配。

我不想重命名 ViewModel,因为我想从 XML 文件配置代理。

那么正确的方法是什么?

谢谢你的帮助

【问题讨论】:

    标签: castle-windsor aop caliburn interceptor


    【解决方案1】:

    这个怎么样?

    void Hack()
    {
        var existing = ViewLocator.TransformName;
        ViewLocator.TransformName = (s, o) =>
                                    existing(s.EndsWith("Proxy")
                                                ? s.Substring(0, s.Length - "Proxy".Length)
                                                : s, o);
    }
    

    【讨论】:

      【解决方案2】:

      最简单的方法(并且可能是健壮的)是建议 Caliburn 的 ViewLocator 使用的不是视图模型代理的类型,而是被代理的视图模型的类型:

      public static void AddViewLocatorRuleForProxiedViewModels()
      {
          var originalViewTypeLocator = ViewLocator.LocateTypeForModelType;
      
          ViewLocator.LocateTypeForModelType = (modelType, displayLocation, context) =>
          {
              var viewModelType = modelType;
      
              var viewModelTypeName = viewModelType.FullName;
              if (viewModelTypeName.StartsWith("Castle.Proxies") && viewModelTypeName.EndsWith("Proxy"))
                  viewModelType = viewModelType.BaseType;
      
              return originalViewTypeLocator(viewModelType, displayLocation, context);
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 2011-02-26
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2010-12-12
        • 1970-01-01
        相关资源
        最近更新 更多