在我们的实际应用程序中,我们定义了一个属性,用于启用方法或类的日志记录(通常的 AOP 用例)。当我们将此属性应用于 WPF 窗口类时,Ninject 无法创建此类的对象。这是重现该问题的最小示例:
用于日志记录的虚拟拦截器:
public class MyInterceptor: IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Calling {0} at {1}", invocation.Request.Method.Name, DateTime.Now);
invocation.Proceed();
}
}
对应的属性:
public class MyAttribute: InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return new MyInterceptor();
}
}
窗口类(完全为空,里面只有自动生成的空网格):
[My]
public partial class MainWindow: Window
{
public MainWindow()
{
InitializeComponent();
}
}
最后是请求对象的应用程序启动代码:
public partial class App: Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
var kernel = new StandardKernel(new NinjectSettings() { LoadExtensions = false }, new DynamicProxyModule());
var window = kernel.Get<MainWindow>();
window.ShowDialog();
}
}
kernel.Get<MainWindow>();
当通过an请求窗口时,TargetInvocationException
会抛出一个内部异常,告诉我Castle.Proxies.MainWindowProxy
没有由 URI 指定的资源,我们的程序集的短名称"/NinjectInterceptionWPF;component/mainwindow.xaml"
在哪里。NinjectInterceptionWPF
当我们查看自动创建InitializeComponent
的时,MainWindow
我们可以看到创建了一个 URI 来处理 XAML 代码,而代理似乎缺少该 URI:
System.Uri resourceLocater = new System.Uri("/NinjectInterceptionWPF;component/mainwindow.xaml", System.UriKind.Relative);
#line 1 "..\..\..\MainWindow.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
我已经玩了一点,并尝试使用绝对 URI,但LoadComponent
只接受相对 URI。
一些互联网搜索表明,很多人使用 Ninject Interception 和 DynmaicProxy 进行 WPF 绑定(INotifyPropertyChanged),所以我认为总的来说应该可以构建 WPF 窗口的代理。
但是怎么做?