Permalink
Browse files

Added the interception framework

  • Loading branch information...
1 parent 042bc73 commit 6dbad3a1198ac7add338673353403a4e44974942 @adrianaisemberg adrianaisemberg committed Oct 26, 2011
View
@@ -79,13 +79,20 @@
<Compile Include="EmptyAttribute.cs" />
<Compile Include="Exceptions.cs" />
<Compile Include="GlobalAttribute.cs" />
+ <Compile Include="Interception\ArgumentsCollection.cs" />
+ <Compile Include="Interception\PostVerbExecutionAttribute.cs" />
+ <Compile Include="Interception\PostVerbExecutionContext.cs" />
+ <Compile Include="Interception\IVerbExecutionContext.cs" />
+ <Compile Include="Interception\PreVerbExecutionAttribute.cs" />
+ <Compile Include="Interception\PreVerbExecutionContext.cs" />
<Compile Include="Method.cs" />
<Compile Include="Parameter.cs" />
<Compile Include="ParameterAttribute.cs" />
<Compile Include="ParametersExpressionValidator.cs" />
<Compile Include="Parser.cs" />
<Compile Include="IValidation.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ReadOnlyDictionary.cs" />
<Compile Include="Serialization.cs" />
<Compile Include="TypeValidator.cs" />
<Compile Include="Utils.cs" />
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+
+namespace CLAP.Interception
+{
+ public class ArgumentsCollection : ReadOnlyDictionary<string, Value>
+ {
+ #region Constructors
+
+ public ArgumentsCollection(Dictionary<string, string> inputArgs, List<object> values)
+ {
+ Dict = new Dictionary<string, Value>();
+
+ var index = 0;
+
+ foreach (var kvp in inputArgs)
+ {
+ Dict.Add(kvp.Key, new Value(kvp.Value, values[index]));
+
+ index++;
+ }
+ }
+
+ #endregion Constructors
+ }
+
+ public sealed class Value
+ {
+ public string StringValue { get; private set; }
+ public object ObjectValue { get; private set; }
+
+ public Value(string stringValue, object value)
+ {
+ StringValue = stringValue;
+ ObjectValue = value;
+ }
+ }
+}
@@ -0,0 +1,10 @@
+
+namespace CLAP.Interception
+{
+ public interface IVerbExecutionContext
+ {
+ Method Method { get; }
+ object Target { get; }
+ ArgumentsCollection Arguments { get; }
+ }
+}
@@ -0,0 +1,10 @@
+using System;
+
+namespace CLAP.Interception
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public sealed class PostVerbExecutionAttribute : Attribute
+ {
+ }
+}
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+
+namespace CLAP.Interception
+{
+ public sealed class PostVerbExecutionContext : IVerbExecutionContext
+ {
+ #region Properties
+
+ public Method Method { get; private set; }
+ public object Target { get; private set; }
+ public ArgumentsCollection Arguments { get; private set; }
+
+ public bool Cancelled { get; private set; }
+
+ public Dictionary<object, object> UserContext { get; private set; }
+
+ #endregion Properties
+
+ #region Constructors
+
+ internal PostVerbExecutionContext(
+ Method method,
+ object target,
+ ArgumentsCollection arguments,
+ bool cancelled,
+ Dictionary<object, object> userContext)
+ {
+ Method = method;
+ Target = target;
+ Arguments = arguments;
+ Cancelled = cancelled;
+ UserContext = userContext;
+ }
+
+ #endregion Constructors
+ }
+}
@@ -0,0 +1,10 @@
+using System;
+
+namespace CLAP.Interception
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
+ public sealed class PreVerbExecutionAttribute : Attribute
+ {
+ }
+}
@@ -0,0 +1,35 @@
+using System.Collections.Generic;
+
+namespace CLAP.Interception
+{
+ public sealed class PreVerbExecutionContext : IVerbExecutionContext
+ {
+ #region Properties
+
+ public Method Method { get; private set; }
+ public object Target { get; private set; }
+ public ArgumentsCollection Arguments { get; private set; }
+
+ public bool Cancel { get; set; }
+
+ public Dictionary<object, object> UserContext { get; set; }
+
+ #endregion Properties
+
+ #region Constructors
+
+ internal PreVerbExecutionContext(
+ Method method,
+ object target,
+ ArgumentsCollection arguments)
+ {
+ Method = method;
+ Target = target;
+ Arguments = arguments;
+
+ UserContext = new Dictionary<object, object>();
+ }
+
+ #endregion Constructors
+ }
+}
View
@@ -7,7 +7,7 @@ namespace CLAP
/// <summary>
/// A method descriptor
/// </summary>
- internal sealed class Method
+ public sealed class Method
{
#region Properties
View
@@ -6,6 +6,7 @@
#if !FW2
using System.Linq;
+using CLAP.Interception;
#endif
@@ -355,9 +356,36 @@ private void RunInternal(string[] args, object obj)
throw new UnhandledParametersException(inputArgs);
}
+ Execute(obj, method, inputArgs, parameterValues);
+ }
+
+ private static void Execute(
+ object target,
+ Method method,
+ Dictionary<string, string> inputArgs,
+ List<object> values)
+ {
+ var arguments = new ArgumentsCollection(inputArgs, values);
+
+ // pre-interception
+ //
+ var preVerbExecutionContext = new PreVerbExecutionContext(method, target, arguments);
+
+ // validate the arguments so they weren't changed after the interception
+ //
+
// invoke the method with the list of parameters
//
- method.MethodInfo.Invoke(obj, parameterValues.ToArray());
+ method.MethodInfo.Invoke(target, values.ToArray());
+
+ // post-interception
+ //
+ var postVerbExecutionContext = new PostVerbExecutionContext(
+ method,
+ target,
+ arguments,
+ preVerbExecutionContext.Cancel,
+ preVerbExecutionContext.UserContext);
}
private static void ValidateVerbInput(Method method, ParameterInfo[] methodParameters, List<object> parameterValues)
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+
+namespace CLAP
+{
+ public class ReadOnlyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
+ {
+ #region Properties
+
+ protected Dictionary<TKey, TValue> Dict { get; set; }
+
+ public int Count
+ {
+ get { return Dict.Count; }
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get { return Dict.Keys; }
+ }
+
+ public ICollection<TValue> Values
+ {
+ get { return Dict.Values; }
+ }
+
+ #endregion Properties
+
+ #region Methods
+
+ public bool ContainsKey(TKey key)
+ {
+ return Dict.ContainsKey(key);
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ return Dict.TryGetValue(key, out value);
+ }
+
+ public TValue this[TKey key]
+ {
+ get
+ {
+ return Dict[key];
+ }
+ }
+
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ return Dict.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return Dict.GetEnumerator();
+ }
+
+ #endregion Methods
+ }
+}

0 comments on commit 6dbad3a

Please sign in to comment.