C# 具有Ninject拦截、Castle DynamicProxy和WPF窗口的AOP:Can';在窗口的DynamicProxy中找不到XAML资源
在我们的实际应用程序中,我们定义了一个属性,用于启用方法或类的登录(通常的AOP用例)。当我们将此属性应用于WPF窗口类时,Ninject无法创建此类的对象。下面是重现该问题的一个简单示例: 用于日志记录的虚拟拦截器:C# 具有Ninject拦截、Castle DynamicProxy和WPF窗口的AOP:Can';在窗口的DynamicProxy中找不到XAML资源,c#,wpf,ninject,aop,ninject-interception,C#,Wpf,Ninject,Aop,Ninject Interception,在我们的实际应用程序中,我们定义了一个属性,用于启用方法或类的登录(通常的AOP用例)。当我们将此属性应用于WPF窗口类时,Ninject无法创建此类的对象。下面是重现该问题的一个简单示例: 用于日志记录的虚拟拦截器: public class MyInterceptor: IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Calling {0} at
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();
}
}
对应的属性:
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();
}
}
窗口类(完全为空,内部只有自动生成的空网格):
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();
}
}
最后是请求对象的应用程序启动代码:
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();
}
}
我已经尝试过使用绝对URI,但是LoadComponent
只接受相对URI
一些互联网搜索显示,很多人使用Ninject拦截和DynmaicProxy进行WPF绑定(INotifyPropertyChanged),因此我认为一般来说,应该可以构建WPF窗口的代理
但是如何实现呢?Ninject的拦截扩展创建了一个新的动态程序集。这意味着您将无法使用相对路径加载资源。但这里的问题是,您是否真的想为视图创建一个动态代理。通常您应该在ViewModel上执行此操作。好的,所以这是不可能的,不是吗?WPF应用程序不遵循MVVM模式,因为它或多或少是用于可视化库API的GUI包装,并且没有任何可用于绑定的数据(如果您输入库调用的返回值等)。如果遵循MVVM模式,则视图不需要实现INotifyPropertyChanged。这是视图模型关注的问题!即使您的应用程序只显示一个API,我想您也需要调用演示的API上的东西,这些东西应该在命令中完成(由ViewModel拥有)