実際のアプリケーションでは、メソッドまたはクラスでのロギングを有効にするために使用される属性を定義しました (通常の 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>();
を介してウィンドウを要求すると、アセンブリの短い名前であるURIで指定されたリソースがないことTargetInvocationException
を示す内部例外がスローされます。Castle.Proxies.MainWindowProxy
"/NinjectInterceptionWPF;component/mainwindow.xaml"
NinjectInterceptionWPF
自動的に作成された をInitializeComponent
確認MainWindow
すると、XAML コードをアドレス指定するために URI が作成されていることがわかります。これは、プロキシに不足しているようです。
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
相対URIのみを受け入れました。
一部のインターネット検索では、多くの人が WPF バインディング (INotifyPropertyChanged) に Ninject Interception と DynmaicProxy を使用しているため、一般的には WPF ウィンドウのプロキシを構築できるはずだと思います。
しかし、どのように?