我想用Castle Windsor Interceptor创建自己的方面并应用于View Model类。
正如我所说,我使用Caliburn MVVM框架而在DI上使用Caste Windsor。一切都很好。
例如,我创建了简单的loggging拦截器,这里是:
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.Write("Log: Method Called: " + invocation.Method.Name);
invocation.Proceed();
}
}
这是一个简单的View Model类 - 它是“tab item”:
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,我没有注册任何View。
代理的目标是TabViewModel,但我认为问题在于命名不匹配。
我不想重命名ViewModel,因为我想从XML文件配置代理。
那么正确的方法是什么?
感谢您的帮助
答案 0 :(得分:1)
这个怎么样?
void Hack()
{
var existing = ViewLocator.TransformName;
ViewLocator.TransformName = (s, o) =>
existing(s.EndsWith("Proxy")
? s.Substring(0, s.Length - "Proxy".Length)
: s, o);
}
答案 1 :(得分:0)
最简单的方法(也可能是健壮的)是建议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);
};
}