0

次のような単純なデコレータ クラスがあります。パブリック メソッドがすべて、装飾対象のクラスの新しいインスタンスを作成し、呼び出しをそのインスタンスに転送する方法に注目してください。

このクラスの問題は、IMyService更新されるたびに、このプロキシ クラスも更新する必要があることです。

public class MyProxyService : IMyService
{
    readonly IMyServiceFactory _realServiceFactory;

    public MyProxyService(IMyServiceFactory realServiceFactory)
    {
        _realServiceFactory = realServiceFactory;
    }

    private IMyService CreateRealService()
    {
        return _realServiceFactory.CreateRealService();
    }

    public int A()
    {
        return CreateRealService().A();
    }

    public int B(int b1)
    {
        return CreateRealService().B(int b1);
    }

    public int C(int c1, int c2)
    {
        return CreateRealService().C(c1,c2);
    }

    public int D(int d1, int d2, int d3)
    {
        return CreateRealService().D(d1,d2,d3);
    }
    public void E()
    {
        CreateRealService().E();
    }
}

を使用して動的バージョンを作成しようとしましたが、Castle.DynamicProxyこれまでのところ運がありません。

このようなデコレータを動的に作成するための簡単で良い方法を知っている人はいますか?

4

1 に答える 1

4

DynamicProxy.ProxyGeneratorCreateInterfaceProxyWithTargetInterface(..)を使用して、これを機能させることができました。

最初に動的プロキシ ファクトリを作成しました。これは、提供された によって各メソッドがインターセプトされるプロキシ オブジェクトを返しますIInterceptor

public class MyDynamicallyDecoratedServiceClientFactory
{
    readonly ProxyGenerator _proxyGenerator;
    readonly IInterceptor _interceptor;
    public MyServiceClientFactory(IInterceptor interceptor)
    {
        _interceptor = interceptor;
        _proxyGenerator = new ProxyGenerator();
    }
    public IMyService Create()
    {
        IMyService proxy = _proxyGenerator.CreateInterfaceProxyWithTargetInterface<IMyService>(null, _interceptor);
        return proxy;
    }
}

次に、インターセプターを実装しました。メソッド呼び出しごとに、このインターセプターが呼び出さIMyServiceれ、提供された から新しい が作成されIMyServiceFactory、メソッド呼び出しがその新しいインスタンスに委任されます。

public class MyServiceClientInterceptor : IInterceptor
{
    readonly IMyServiceFactory _svcFactory;
    public MyServiceClientInterceptor(IMyServiceFactory svcFactory)
    {
        _svcFactory = svcFactory;
    }
    public void Intercept(IInvocation invocation)
    {
        IMyService realService = _svcFactory.Create();
        IChangeProxyTarget changeProxyTarget = invocation as IChangeProxyTarget;
        changeProxyTarget.ChangeInvocationTarget(realService);
        invocation.Proceed();
    }
}

最後に、これらすべてを利用するには:

// Create a service factory (the to-be-decorated class)
IMyServiceFactory myRealServiceFactory = /* ... */;

// Create a factory that will create decorated services
MyServiceClientInterceptor interceptor = 
        new MyServiceClientInterceptor(myRealServiceFactory);
MyDynamicallyDecoratedServiceClientFactory svcFactory =  
        new MyDynamicallyDecoratedServiceClientFactory(interceptor);

// Create a service client
IMyService svc = svcFactory.Create();

// Use it!
svcProxy.A();
于 2013-01-23T20:42:48.297 に答える