저는이 문제가 아니라 여러 가지 해결책을 사용합니다.
1- RealProxy에서 사용자 지정 프록시를 파생시키고 .NET Remoting 인프라에서 제공하는 호출 차단을 활용할 수 있습니다. 이점은 매우 쉽지만 제한 사항은 인터페이스를 프록시 처리하고 리플렉션을 사용하여 내부 클래스의 멤버를 호출해야하거나 프록시되는 클래스가 MarshalByRrefObject에서 상속해야한다는 것입니다.
코드 샘플을 제공하는 것을 망설이지 만, 완료되지 않았기 때문에 주저하지만 나는 아마도 불타 올 것입니다. 그러나 여기에 올바른 클래스 등을 가르쳐 줄 수있는 10 분짜리 코드가 있습니다. IMethodCallMessage 만 처리하므로 데모로 작동해야합니다.
class MyClass : MarshalByRefObject
{
public int Age
{
get;
set;
}
}
MyClass o = LoggingProxy<MyClass>.Create();
o.Age = 10;
위 MyClass에의 프록시 인스턴스 set_Age로 통화를 기록 할 다음
class LoggingProxy<T> : RealProxy where T : MarshalByRefObject, new()
{
T _innerObject;
public static T Create()
{
LoggingProxy<T> realProxy = new LoggingProxy<T>();
T transparentProxy = (T)realProxy.GetTransparentProxy();
return transparentProxy;
}
private LoggingProxy() : base(typeof(T))
{
_innerObject = new T();
}
public override IMessage Invoke(IMessage msg)
{
if (msg is IMethodCallMessage)
{
IMethodCallMessage methodCall = msg as IMethodCallMessage;
System.Diagnostics.Debug.WriteLine("Enter: " + methodCall.MethodName);
IMessage returnMessage = RemotingServices.ExecuteMessage(_innerObject, msg as IMethodCallMessage);
System.Diagnostics.Debug.WriteLine("Exit: " + methodCall.MethodName);
return returnMessage;
}
return null;
}
}
이 사용될 수있다.
2 - 그러나 또 다른 대안은 전달하는 유형에서 파생 된 유형을 동적으로 생성하고 기본 유형의 모든 메소드 및 특성의 구현을 제공하는 프록시 클래스를 작성하는 것입니다. 생성 된 메소드 등은 RealProxy 예제와 비슷한 기본 클래스 구현 등을 호출하는 로깅을 수행합니다. VS var 유형을 사용하면 실제로 유형에서 계승해야하는 필요성을 피할 수 있고이 프록시에 대한 집계를 사용하므로 인텔리 센스 지원이 제공되며 모든 메소드/속성을 가상으로 만들 필요가 없습니다. 죄송합니다. 예를 들어, 지금은 조금 지나치게 많습니다. 하지만 동적 유형의 건물에 대해 CodeDom 이상인 경우 Reflection.Emit을 사용할 수 있습니다. 동적 코드는 @ tvanfosson의 대답에서 제안 된 것과 비슷한 것을 할 수 있습니다.
3 그리고 마지막으로 DynamicObject을 사용하면 단점은 메서드 호출과 intelli-sense의 컴파일 시간 확인을 컴파일하지 않는다는 것입니다. 여기에도 최소한의 예가 있습니다. 다음
dynamic o2 = new DynamicProxy(new MyClass());
o.Age = 10;
같은 것을 사용
public class DynamicProxy : System.Dynamic.DynamicObject
{
private object _innerObject;
private Type _innerType;
public DynamicProxy(object inner)
{
if (inner == null) throw new ArgumentNullException("inner");
_innerObject = inner;
_innerType = _innerObject.GetType();
}
public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
null, _innerObject, args);
}
catch (MissingMemberException)
{
return base.TryInvokeMember(binder, args, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
result = _innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty,
null, _innerObject, null);
}
catch (MissingMemberException)
{
return base.TryGetMember(binder, out result);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value)
{
System.Diagnostics.Debug.WriteLine("Enter: ", binder.Name);
try
{
_innerType.InvokeMember(
binder.Name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
null, _innerObject, new object[]{ value });
}
catch (MissingMemberException)
{
return base.TrySetMember(binder, value);
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ", binder.Name);
}
return true;
}
public override string ToString()
{
try
{
System.Diagnostics.Debug.WriteLine("Enter: ToString");
return _innerObject.ToString();
}
finally
{
System.Diagnostics.Debug.WriteLine("Exit: ToString");
}
}
}
은 다른 방법은 미리 백업 솔루션의 일부를 볼 수 있습니다, 자신의 솔루션을 압연에 대한 몇 가지 옵션이 있습니다. 어느 쪽이 더 좋은 방법일까요? 그러나 이것은 아마도 몇몇 솔루션이 어떻게 구현되었는지에 대한 통찰력을 줄 것입니다.
당신은 정말로 무엇을하려고합니까? params (http://msdn.microsoft.com/en-us/library/w5zay9db(VS.71).aspx)를 사용하여 해결할 수 있습니까? – Tom
위에서 쓴 것처럼, 기본적으로 "내부"에있는 메서드가 호출 될 때마다 로그에 메시지를 작성하려고합니다. –
@Tom : 네, 필요한 부분에 가깝습니다. –