2012-02-12 113 views
0

我想用Castle Windsor拦截器创建自己的方面,并应用于视图模型类。城堡温莎拦截器上Caliburn查看模型

正如我所说,我使用Caliburn MVVM框架和DI我使用卡斯温莎。一切正常。

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

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

这是简单的视图模型类 - 它是 “标签项”:

public class TabViewModel : Screen, 
    ITabViewModel 
{ 

} 

当我配置IoC和流利的API我想在视图模型类上应用这个拦截器。

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

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

当我试图从国际奥委会挑选视图模型:

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我没有注册任何View。

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

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

那么什么是正确的方法?

谢谢你的帮助

回答

1

这是怎么回事?

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

最简单的方法(可能强劲)是建议卡利的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); 
    }; 
}