在我们的实际应用程序中,我们定义了一个属性,用于在方法或类中启用日志记录(通常的 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>();
请求窗口时一个TargetInvocationException
抛出内部异常告诉我 Castle.Proxies.MainWindowProxy
没有 URI "/NinjectInterceptionWPF;component/mainwindow.xaml"
指定的资源其中 NinjectInterceptionWPF
是我们程序集的简称。
当我们查看自动创建的 InitializeComponent
的 MainWindow
我们可以看到创建了一个 URI 来处理 XAML 代码,代理似乎缺少该代码:
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
只接受相对的。
一些互联网搜索显示很多人使用 Ninject Interception 和 DynmaicProxy 进行 WPF 绑定(bind)(INotifyPropertyChanged),所以我认为一般来说应该可以构建 WPF 窗口的代理。
但是如何呢?
最佳答案
Ninject 的拦截扩展创建了一个新的动态程序集。这意味着您将无法使用相对路径加载资源。但这里的问题是你是否真的想为 View 创建一个动态代理。通常您应该在 ViewModel 上执行此操作。
关于c# - 带有 Ninject 拦截、CaSTLe DynamicProxy 和 WPF 窗口的 AOP : Can't find XAML resource in DynamicProxy of window,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11226271/