C#에서 프록시 또는 데코레이터 클래스를 구현하는 가장 짧은 방법은 무엇입니까?
-
21-08-2019 - |
문제
Ivehicle을 구현하는 클래스 자동차가 있고 모든 전화를 자동차로 전달하고 계산하는 데코레이터로 감고 싶을 때 어떻게 하시겠습니까?
Ruby에서는 방법없이 데코레이터를 만들고 Method_missing을 사용하여 모든 통화를 자동차 객체로 전달할 수 있습니다.
Java에서는 하나의 메소드를 통해 모든 코드를 실행하고 나중에 전달하는 프록시 객체를 빌드 할 수 있습니다.
C#에서 할 수있는 유사한 일이 있습니까?
업데이트:
답변과 System.reflection.emit에 대해 읽은 내용을 기반으로 다음과 비슷한 메소드를 작성할 수 있어야합니다.
Type proxyBuilder(Type someType, delagate functionToBeApplied, Object forward)
여기서 유형은 tothe 유형의 모든 인터페이스를 구현하고 functionTobeAppied를 실행 한 다음 메소드 호출을 객체로 전달합니다.
그 일을하는 lib가 있습니까, 아니면 내 자신을 써야합니까?
해결책
프록시를 위해 표준 유형을 사용하려면 "RealProxy"를 살펴볼 수 있습니다. 그러나 사용하기에는 약간의 번거 로움입니다 (수업이 MarshalbyRefobject에서 상속해야합니다).
public class TestProxy<T> : RealProxy where T : class
{
public T Instance { get { return (T)GetTransparentProxy(); } }
private readonly MarshalByRefObject refObject;
private readonly string uri;
public TestProxy() : base(typeof(T))
{
refObject = (MarshalByRefObject)Activator.CreateInstance(typeof(T));
var objRef = RemotingServices.Marshal(refObject);
uri = objRef.URI;
}
// You can find more info on what can be done in here off MSDN.
public override IMessage Invoke(IMessage message)
{
Console.WriteLine("Invoke!");
message.Properties["__Uri"] = uri;
return ChannelServices.SyncDispatchMessage(message);
}
}
또는 Castle에서 "DynamicProxy"를 얻을 수 있습니다. 내 경험에서 조금 더 잘 작동합니다 ..
당신이 당신이 당신이 당신이 큰 성능을 얻지 못할 것인지를 사용하지 않는다면, 나는 주로 처음에는 느리게 될 수있는 통화에 주로 사용합니다. 그러나 당신이 원한다면 시도해 볼 수 있습니다.
Marc의 솔루션은 더 나은 성능을 제공합니다.
다른 팁
불행히도 C#에는 혼합 지지대가 없습니다. 따라서 모든 방법을 구현하거나 중대한 반사를 사용해야합니다. 다른 대안은 (선택 사항) 프록시 /데코레이터 기본 클래스입니다 ...
abstract class FooBase : IFoo {
protected FooBase(IFoo next) {this.next = next;}
private readonly IFoo next;
public virtual void Bar() { // one of the interface methods
next.Bar();
}
public virtual int Blop() { // one of the interface methods
return next.Blop();
}
// etc
}
그 다음에
class SomeFoo : FooBase {
public SomeFoo(IFoo next) : base(next) {}
public override void Bar() {...}
}
그 사용에 주목합니다 FooBase
엄격하게 선택 사항입니다. 모든 IFOO가 허용됩니다.