Commit d6d35f2
Changed files (41)
trunk
product
Gorilla.Commons.Infrastructure
Gorilla.Commons.Infrastructure.ThirdParty
Castle
DynamicProxy
Interceptors
Windsor
Configuration
MoMoney.Infrastructure
trunk/product/Gorilla.Commons.Infrastructure/Proxies/ExceptionExtensions.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Reflection;
+
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ static public class ExceptionExtensions
+ {
+ static readonly MethodInfo method =
+ typeof (Exception).GetMethod("InternalPreserveStackTrace",
+ BindingFlags.NonPublic | BindingFlags.Instance);
+
+ static public Exception preserve_stack_trace(this Exception exception)
+ {
+ method.Invoke(exception, new object[0]);
+ return exception;
+ }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/IInterceptor.cs
@@ -0,0 +1,7 @@
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ public interface IInterceptor
+ {
+ void Intercept(IInvocation invocation);
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/IInvocation.cs
@@ -0,0 +1,12 @@
+using System.Reflection;
+
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ public interface IInvocation
+ {
+ void Proceed();
+ object[] Arguments { get; }
+ MethodInfo Method { get; }
+ object ReturnValue { get; set; }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/MethodCallInvocation.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Remoting.Messaging;
+using Gorilla.Commons.Utility.Extensions;
+
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ public class MethodCallInvocation<T> : IInvocation
+ {
+ readonly IMethodCallMessage call;
+ readonly T target;
+ readonly Stack<IInterceptor> interceptors;
+
+ public MethodCallInvocation(IEnumerable<IInterceptor> interceptors, IMethodCallMessage call, T target)
+ {
+ this.call = call;
+ this.target = target;
+ this.interceptors = new Stack<IInterceptor>(interceptors);
+ Arguments = call.Properties["__Args"].downcast_to<object[]>();
+ Method = call.MethodBase.downcast_to<MethodInfo>();
+ }
+
+ public object[] Arguments { get; set; }
+
+ public MethodInfo Method { get; set; }
+
+ public object ReturnValue { get; set; }
+
+ public void Proceed()
+ {
+ if (interceptors.Count > 0)
+ {
+ interceptors.Pop().Intercept(this);
+ return;
+ }
+
+ try
+ {
+ ReturnValue = call.MethodBase.Invoke(target, Arguments);
+ }
+ catch (TargetInvocationException e)
+ {
+ throw e.InnerException.preserve_stack_trace();
+ }
+ }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/ProxyFactory.cs
@@ -0,0 +1,10 @@
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ static public class ProxyFactory
+ {
+ static public T Create<T>(T target, params IInterceptor[] interceptors)
+ {
+ return new RemotingProxyFactory<T>(target, interceptors).CreateProxy();
+ }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/ProxyFactorySpecs.cs
@@ -0,0 +1,57 @@
+using developwithpassion.bdd.contexts;
+using Gorilla.Commons.Testing;
+
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ public class ProxyFactorySpecs
+ {
+ }
+
+ public class when_proxying_a_class_with_interceptors_applied : concerns
+ {
+ context c = () =>
+ {
+ interceptors = new MyNameIsSlimShadyInterceptor();
+ marshal_mathers = new Person("marshall mathers");
+ };
+
+ because b =
+ () => { some_celebrity = ProxyFactory.Create<IPerson>(marshal_mathers, interceptors); };
+
+ it should_all_each_interceptor_to_intercept_the_invocation =
+ () => some_celebrity.what_is_your_name().should_be_equal_to("slim shady");
+
+ static Person marshal_mathers;
+ static IPerson some_celebrity;
+ static IInterceptor interceptors;
+ }
+
+ public interface IPerson
+ {
+ string what_is_your_name();
+ }
+
+ public class Person : IPerson
+ {
+ readonly string my_name;
+
+ public Person(string my_name)
+ {
+ this.my_name = my_name;
+ }
+
+ public string what_is_your_name()
+ {
+ return my_name;
+ }
+ }
+
+ public class MyNameIsSlimShadyInterceptor : IInterceptor
+ {
+ public void Intercept(IInvocation invocation)
+ {
+ invocation.Proceed();
+ invocation.ReturnValue = "slim shady";
+ }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Proxies/RemotingProxyFactory.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Proxies;
+using Gorilla.Commons.Utility.Extensions;
+
+namespace Gorilla.Commons.Infrastructure.Proxies
+{
+ public interface IProxyFactory<T>
+ {
+ T CreateProxy();
+ }
+
+ public class RemotingProxyFactory<T> : RealProxy, IProxyFactory<T>
+ {
+ readonly T target;
+ readonly IEnumerable<IInterceptor> interceptors;
+
+ public RemotingProxyFactory(T target, IEnumerable<IInterceptor> interceptors) : base(typeof (T))
+ {
+ this.target = target;
+ this.interceptors = interceptors;
+ }
+
+ public override IMessage Invoke(IMessage message)
+ {
+ if (message.is_an_implementation_of<IMethodCallMessage>())
+ {
+ var call = message.downcast_to<IMethodCallMessage>();
+ var invocation = new MethodCallInvocation<T>(interceptors, call, target);
+ invocation.Proceed();
+ return ReturnValue(invocation.ReturnValue, invocation.Arguments, call);
+ }
+ return null;
+ }
+
+ IMessage ReturnValue(object return_value, object[] out_parameters, IMethodCallMessage call)
+ {
+ return new ReturnMessage(return_value,
+ out_parameters,
+ out_parameters == null ? 0 : out_parameters.Length,
+ call.LogicalCallContext, call);
+ }
+
+ public T CreateProxy()
+ {
+ return GetTransparentProxy().downcast_to<T>();
+ }
+ }
+}
\ No newline at end of file
trunk/product/Gorilla.Commons.Infrastructure/Gorilla.Commons.Infrastructure.csproj
@@ -84,6 +84,13 @@
<Compile Include="Logging\Log.cs" />
<Compile Include="Logging\LoggingExtensions.cs" />
<Compile Include="Logging\LogSpecs.cs" />
+ <Compile Include="Proxies\ExceptionExtensions.cs" />
+ <Compile Include="Proxies\IInterceptor.cs" />
+ <Compile Include="Proxies\IInvocation.cs" />
+ <Compile Include="Proxies\MethodCallInvocation.cs" />
+ <Compile Include="Proxies\ProxyFactory.cs" />
+ <Compile Include="Proxies\ProxyFactorySpecs.cs" />
+ <Compile Include="Proxies\RemotingProxyFactory.cs" />
<Compile Include="Reflection\ApplicationAssembly.cs" />
<Compile Include="Reflection\EnvironmentExtensions.cs" />
<Compile Include="Reflection\IAssembly.cs" />
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/IMethodCallTracker.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/IMethodCallTracker.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/MethodCallTracker.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/MethodCallTracker.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/MethodCallTrackerSpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/MethodCallTrackerSpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/RunOnBackgroundThreadInterceptor.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/RunOnBackgroundThreadInterceptor.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/RunOnBackgrounThreadInterceptorSpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/RunOnBackgrounThreadInterceptorSpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Interceptors/SelectiveInterceptor.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Interceptors/SelectiveInterceptor.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IConstraintSelector.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IConstraintSelector.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IInterceptorConstraint.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IInterceptorConstraint.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IInterceptorConstraintFactory.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IInterceptorConstraintFactory.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IMethodCallTrackerFactory.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IMethodCallTrackerFactory.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/InterceptorConstraintFactorySpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/InterceptorConstraintFactorySpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/InterceptorConstraintSpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/InterceptorConstraintSpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IProxyBuilder.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IProxyBuilder.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/IProxyFactory.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/IProxyFactory.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/Lazy.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/Lazy.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/LazyLoadedInterceptor.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/LazyLoadedInterceptor.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/LazySpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/LazySpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/ProxyBuilder.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/ProxyBuilder.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/ProxyBuilderSpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/ProxyBuilderSpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/ProxyFactory.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/ProxyFactory.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Proxies/ProxyFactorySpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/DynamicProxy/ProxyFactorySpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/ApplyLoggingInterceptor.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/ApplyLoggingInterceptor.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/ComponentRegistrationConfiguration.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/ComponentRegistrationConfiguration.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/ConfigureComponentLifestyle.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/ConfigureComponentLifestyle.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/IComponentExclusionSpecification.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/IComponentExclusionSpecification.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/LogComponent.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/LogComponent.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/LoggingInterceptor.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/LoggingInterceptor.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/Configuration/RegisterComponentContract.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/Configuration/RegisterComponentContract.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/WindsorContainerFactory.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/WindsorContainerFactory.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/WindsorDependencyRegistry.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/WindsorDependencyRegistry.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Windsor/WindsorDependencyRegistrySpecs.cs → trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Castle/Windsor/WindsorDependencyRegistrySpecs.cs
File renamed without changes
trunk/product/Gorilla.Commons.Infrastructure.ThirdParty/Gorilla.Commons.Infrastructure.ThirdParty.csproj
@@ -95,37 +95,37 @@
<Compile Include="IDependencyRegistration.cs" />
<Compile Include="Log4Net\Log4NetLogFactory.cs" />
<Compile Include="Log4Net\Log4NetLogger.cs" />
- <Compile Include="Proxies\IConstraintSelector.cs" />
- <Compile Include="Proxies\IInterceptorConstraint.cs" />
- <Compile Include="Proxies\IInterceptorConstraintFactory.cs" />
- <Compile Include="Proxies\IMethodCallTrackerFactory.cs" />
- <Compile Include="Proxies\InterceptorConstraintFactorySpecs.cs" />
- <Compile Include="Proxies\InterceptorConstraintSpecs.cs" />
- <Compile Include="Proxies\Interceptors\IMethodCallTracker.cs" />
- <Compile Include="Proxies\Interceptors\MethodCallTracker.cs" />
- <Compile Include="Proxies\Interceptors\MethodCallTrackerSpecs.cs" />
- <Compile Include="Proxies\Interceptors\RunOnBackgroundThreadInterceptor.cs" />
- <Compile Include="Proxies\Interceptors\RunOnBackgrounThreadInterceptorSpecs.cs" />
- <Compile Include="Proxies\Interceptors\SelectiveInterceptor.cs" />
- <Compile Include="Proxies\IProxyBuilder.cs" />
- <Compile Include="Proxies\IProxyFactory.cs" />
- <Compile Include="Proxies\Lazy.cs" />
- <Compile Include="Proxies\LazyLoadedInterceptor.cs" />
- <Compile Include="Proxies\LazySpecs.cs" />
- <Compile Include="Proxies\ProxyBuilder.cs" />
- <Compile Include="Proxies\ProxyBuilderSpecs.cs" />
- <Compile Include="Proxies\ProxyFactory.cs" />
- <Compile Include="Proxies\ProxyFactorySpecs.cs" />
- <Compile Include="Windsor\Configuration\ApplyLoggingInterceptor.cs" />
- <Compile Include="Windsor\Configuration\ComponentRegistrationConfiguration.cs" />
- <Compile Include="Windsor\Configuration\ConfigureComponentLifestyle.cs" />
- <Compile Include="Windsor\Configuration\IComponentExclusionSpecification.cs" />
- <Compile Include="Windsor\Configuration\LogComponent.cs" />
- <Compile Include="Windsor\Configuration\LoggingInterceptor.cs" />
- <Compile Include="Windsor\Configuration\RegisterComponentContract.cs" />
- <Compile Include="Windsor\WindsorContainerFactory.cs" />
- <Compile Include="Windsor\WindsorDependencyRegistry.cs" />
- <Compile Include="Windsor\WindsorDependencyRegistrySpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\IConstraintSelector.cs" />
+ <Compile Include="Castle\DynamicProxy\IInterceptorConstraint.cs" />
+ <Compile Include="Castle\DynamicProxy\IInterceptorConstraintFactory.cs" />
+ <Compile Include="Castle\DynamicProxy\IMethodCallTrackerFactory.cs" />
+ <Compile Include="Castle\DynamicProxy\InterceptorConstraintFactorySpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\InterceptorConstraintSpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\IMethodCallTracker.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\MethodCallTracker.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\MethodCallTrackerSpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\RunOnBackgroundThreadInterceptor.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\RunOnBackgrounThreadInterceptorSpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\Interceptors\SelectiveInterceptor.cs" />
+ <Compile Include="Castle\DynamicProxy\IProxyBuilder.cs" />
+ <Compile Include="Castle\DynamicProxy\IProxyFactory.cs" />
+ <Compile Include="Castle\DynamicProxy\Lazy.cs" />
+ <Compile Include="Castle\DynamicProxy\LazyLoadedInterceptor.cs" />
+ <Compile Include="Castle\DynamicProxy\LazySpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\ProxyBuilder.cs" />
+ <Compile Include="Castle\DynamicProxy\ProxyBuilderSpecs.cs" />
+ <Compile Include="Castle\DynamicProxy\ProxyFactory.cs" />
+ <Compile Include="Castle\DynamicProxy\ProxyFactorySpecs.cs" />
+ <Compile Include="Castle\Windsor\Configuration\ApplyLoggingInterceptor.cs" />
+ <Compile Include="Castle\Windsor\Configuration\ComponentRegistrationConfiguration.cs" />
+ <Compile Include="Castle\Windsor\Configuration\ConfigureComponentLifestyle.cs" />
+ <Compile Include="Castle\Windsor\Configuration\IComponentExclusionSpecification.cs" />
+ <Compile Include="Castle\Windsor\Configuration\LogComponent.cs" />
+ <Compile Include="Castle\Windsor\Configuration\LoggingInterceptor.cs" />
+ <Compile Include="Castle\Windsor\Configuration\RegisterComponentContract.cs" />
+ <Compile Include="Castle\Windsor\WindsorContainerFactory.cs" />
+ <Compile Include="Castle\Windsor\WindsorDependencyRegistry.cs" />
+ <Compile Include="Castle\Windsor\WindsorDependencyRegistrySpecs.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Gorilla.Commons.Infrastructure\Gorilla.Commons.Infrastructure.csproj">
@@ -142,8 +142,6 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <Folder Include="Castle\DynamicProxy\Interceptors\" />
- <Folder Include="Castle\Windsor\Configuration\" />
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
trunk/product/MoMoney.Infrastructure/MoMoney.Infrastructure.csproj
@@ -115,11 +115,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <Folder Include="Container\Autofac\" />
- <Folder Include="Container\Windsor\Configuration\" />
- <Folder Include="Logging\Log4Net\" />
<Folder Include="Properties\" />
- <Folder Include="Proxies\Interceptors\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.