次のコードは、Castle.Windsor 2.5.3でそのまま通過しますが、3.1.0にアップグレードすると失敗します。
例外はInvalidProxyConstructorArgumentsExceptionであり、「クラスのプロキシをインスタンス化できません:テスト。パラメーターのないコンストラクターが見つかりませんでした。」と表示されます。
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Component.For<Interceptor>(),
Component.For<Test>().UsingFactoryMethod(() => new Test(""))
.Interceptors<Interceptor>());
var test = container.Resolve<Test>(); //THROWS IN 3.1.0
}
}
public class Test
{
public readonly string S;
public Test(string s)
{
S = s;
}
}
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
}
}
私の実際のコードでは、テストはファクトリメソッドを使用して構築され、リポジトリに挿入されているMongoDatabaseです。
私の実際のコードでは、AbstractFacilityの継承者を使用してインターセプターを登録しています。このようにして、各コンポーネントのインターセプターを登録する必要はありません。インターセプターの使用の両方の形式は、後の解決で同じように機能/失敗するようです(2.5.3 / 3.1.0)。参考までに、施設の短縮版を次に示します。
public class Facility : AbstractFacility
{
protected override void Init() { Kernel.ComponentRegistered += KernelComponentRegistered; }
static void KernelComponentRegistered(string key, IHandler handler)
{
if (typeof(IInterceptor).IsAssignableFrom(handler.ComponentModel.Implementation)) return;
handler.ComponentModel.Interceptors.AddIfNotInCollection(InterceptorReference.ForKey("SomeInterceptor"));
}
}
Castle.Windsorのソースコードを調べたところ、スローするコードは、指定されたクラスの周りにプロキシをラップすることを期待しているため、パラメーターのないコンストラクターを探しています。ただし、2.5.3では、プロキシ生成コードが実行されることはなく、コンテナは(私の考えでは)非プロキシバージョンのTest/MongoDatabaseに解決されると思います。
だから私が推測する2つの質問:1)何が変わったのですか?2)ファクトリメソッドによって解決されたオブジェクトのプロキシを生成せずにインターセプター登録を保持するにはどうすればよいですか?または、コンポーネントのファクトリメソッドを使用してプロキシを生成するにはどうすればよいでしょうか...