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.