AOP с Ninject Interception, Castle DynamicProxy и окном WPF: не удается найти ресурс XAML в DynamicProxy окна

В нашем реальном приложении мы определили атрибут, который используется для включения регистрации в методах или классах (обычный случай использования 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 (INotifyPropertyChanged), поэтому я думаю, что в целом должна быть возможность создать прокси из окна WPF.

Но как?

1 ответ

Расширение перехвата Ninject создало новую динамическую сборку. Это означает, что вы не сможете загружать ресурсы с относительным путем. Но вопрос здесь в том, действительно ли вы хотите создать динамический прокси для представления. Обычно вы должны сделать это на ViewModel.

Другие вопросы по тегам