1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.DynamicProxy
18 using System
.Diagnostics
;
19 using System
.Reflection
;
20 using System
.Runtime
.Serialization
;
21 using Castle
.Core
.Interceptor
;
24 public abstract class AbstractInvocation
: IInvocation
, ISerializable
26 private readonly object proxy
;
27 private readonly object target
;
28 private readonly IInterceptor
[] interceptors
;
29 private readonly Type targetType
;
30 private readonly MethodInfo targetMethod
;
31 private readonly MethodInfo interfMethod
;
32 private object returnValue
;
33 private object[] arguments
;
34 private int execIndex
= -1;
35 private Type
[] genericMethodArguments
= null;
37 protected AbstractInvocation(
38 object target
, object proxy
, IInterceptor
[] interceptors
,
39 Type targetType
, MethodInfo targetMethod
, object[] arguments
)
43 this.interceptors
= interceptors
;
44 this.targetType
= targetType
;
45 this.targetMethod
= targetMethod
;
46 this.arguments
= arguments
;
49 protected AbstractInvocation(
50 object target
, object proxy
, IInterceptor
[] interceptors
,
51 Type targetType
, MethodInfo targetMethod
, MethodInfo interfMethod
,
53 : this(target
, proxy
, interceptors
, targetType
, targetMethod
, arguments
)
55 this.interfMethod
= interfMethod
;
58 public void SetGenericMethodArguments(Type
[] arguments
)
60 genericMethodArguments
= arguments
;
63 public Type
[] GenericArguments
65 get { return genericMethodArguments; }
73 public object InvocationTarget
75 get { return target; }
78 public Type TargetType
80 get { return targetType; }
83 public MethodInfo Method
87 if (interfMethod
== null)
98 public MethodInfo
GetConcreteMethod()
100 return EnsureClosedMethod(Method
);
103 public MethodInfo MethodInvocationTarget
105 get { return targetMethod; }
108 public MethodInfo
GetConcreteMethodInvocationTarget()
110 return EnsureClosedMethod(MethodInvocationTarget
);
113 public object ReturnValue
115 get { return returnValue; }
116 set { returnValue = value; }
119 public object[] Arguments
121 get { return arguments; }
124 public void SetArgumentValue(int index
, object value)
126 arguments
[index
] = value;
129 public object GetArgumentValue(int index
)
131 return arguments
[index
];
134 public void Proceed()
138 if (execIndex
== interceptors
.Length
)
140 InvokeMethodOnTarget();
142 else if (execIndex
> interceptors
.Length
)
144 throw new InvalidOperationException(
145 @"Proceed() cannot delegate to another interceptor. This usually signify a bug in the calling code");
149 interceptors
[execIndex
].Intercept(this);
153 public void GetObjectData(SerializationInfo info
, StreamingContext context
)
155 info
.SetType(typeof(RemotableInvocation
));
156 info
.AddValue("invocation", new RemotableInvocation(this));
159 protected abstract void InvokeMethodOnTarget();
161 private MethodInfo
EnsureClosedMethod(MethodInfo method
)
163 if (method
.ContainsGenericParameters
)
165 Debug
.Assert(genericMethodArguments
!= null);
166 return method
.GetGenericMethodDefinition().MakeGenericMethod(genericMethodArguments
);