Added container accessor to Castle.Core
[castle.git] / Tools / Castle.DynamicProxy2 / Castle.DynamicProxy / AbstractInvocation.cs
blobb42d2108583167b540d7e35aa81a9d7137f747de
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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
17 using System;
18 using System.Diagnostics;
19 using System.Reflection;
20 using System.Runtime.Serialization;
21 using Castle.Core.Interceptor;
23 [Serializable]
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)
41 this.proxy = proxy;
42 this.target = target;
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,
52 object[] arguments)
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; }
68 public object Proxy
70 get { return proxy; }
73 public object InvocationTarget
75 get { return target; }
78 public Type TargetType
80 get { return targetType; }
83 public MethodInfo Method
85 get
87 if (interfMethod == null)
89 return targetMethod;
91 else
93 return interfMethod;
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()
136 execIndex++;
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");
147 else
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);
168 else
170 return method;