C# 具有Ninject拦截、Castle DynamicProxy和WPF窗口的AOP:Can';在窗口的DynamicProxy中找不到XAML资源

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

在我们的实际应用程序中,我们定义了一个属性,用于启用方法或类的登录(通常的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();
    }
}
对应的属性:

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拥有)