Commit a8a9eb2
Changed files (8)
trunk
product
MyMoney
Infrastructure
Container
Windsor
interceptors
windows.ui
trunk/product/MyMoney/Infrastructure/Container/Windsor/WindsorDependencyRegistry.cs
@@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using Castle.Core;
using Castle.Windsor;
+using MoMoney.Infrastructure.proxies;
+using MoMoney.Utility.Core;
using MoMoney.Utility.Extensions;
namespace MoMoney.Infrastructure.Container.Windsor
@@ -53,5 +55,12 @@ namespace MoMoney.Infrastructure.Container.Windsor
{
return "{0}-{1}".formatted_using(interface_type.FullName, implementation_type.FullName);
}
+
+ public void proxy<T>(IConfiguration<IProxyBuilder<T>> configuration)
+ {
+ var builder = new ProxyBuilder<T>();
+ configuration.configure(builder);
+ singleton(builder.create_proxy_for(() => underlying_container.Resolve<T>()));
+ }
}
}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/interceptors/LazySpecs.cs
@@ -23,12 +23,12 @@ namespace MoMoney.Infrastructure.interceptors
public class when_calling_a_method_with_no_arguments_on_a_lazy_loaded_proxy : behaves_like_a_lazy_loaded_object
{
- it should_forward_the_original_call_to_the_target = () => mocking_extensions.was_told_to(target, t => t.OneMethod());
+ it should_forward_the_original_call_to_the_target = () => target.was_told_to(t => t.OneMethod());
context c = () =>
{
target = an<ITargetObject>();
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target).Repeat.Once();
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target).Repeat.Once();
};
because b = () =>
@@ -49,9 +49,8 @@ namespace MoMoney.Infrastructure.interceptors
{
var target = an<ITargetObject>();
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(target, x => x.FirstValueReturningMethod()), 10);
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target)
- .Repeat.Once();
+ target.is_told_to(x => x.FirstValueReturningMethod()).it_will_return(10);
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target) .Repeat.Once();
};
because b = () =>
@@ -71,7 +70,7 @@ namespace MoMoney.Infrastructure.interceptors
context c = () =>
{
var target = an<ITargetObject>();
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target).Repeat.Once();
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target).Repeat.Once();
};
because b = () =>
@@ -86,7 +85,7 @@ namespace MoMoney.Infrastructure.interceptors
behaves_like_a_lazy_loaded_object
{
it should_forward_the_call_to_the_original_target =
- () => mocking_extensions.was_told_to(target, x => x.ValueReturningMethodWithAnArgument(88));
+ () => target.was_told_to(x => x.ValueReturningMethodWithAnArgument(88));
it should_return_the_correct_result = () => result.should_be_equal_to(99);
@@ -94,8 +93,8 @@ namespace MoMoney.Infrastructure.interceptors
{
target = an<ITargetObject>();
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(target, x => x.ValueReturningMethodWithAnArgument(88)), 99);
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target).Repeat.Once();
+ target.is_told_to(x => x.ValueReturningMethodWithAnArgument(88)).it_will_return(99);
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target).Repeat.Once();
};
because b = () =>
@@ -117,7 +116,7 @@ namespace MoMoney.Infrastructure.interceptors
var target = an<ITargetObject>();
target.GetterAndSetterProperty = "mo";
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target).Repeat.Once();
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target).Repeat.Once();
};
because b = () =>
@@ -132,14 +131,12 @@ namespace MoMoney.Infrastructure.interceptors
public class when_setting_the_value_of_a_property_on_a_proxied_object : behaves_like_a_lazy_loaded_object
{
it should_set_the_value_on_the_original_target =
- () => mocking_extensions.was_told_to(target, x => x.GetterAndSetterProperty = "khan");
+ () => target.was_told_to(x => x.GetterAndSetterProperty = "khan");
context c = () =>
{
target = dependency<ITargetObject>();
-
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<ITargetObject>()), target)
- .Repeat.Once();
+ test_container.is_told_to(t => t.get_a<ITargetObject>()).it_will_return(target) .Repeat.Once();
};
because b = () =>
@@ -162,8 +159,8 @@ namespace MoMoney.Infrastructure.interceptors
{
target = an<IGenericInterface<string>>();
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(target, x => x.ValueReturningMethodWithAnArgument("blah")), "hooray");
- mocking_extensions.it_will_return(mocking_extensions.is_told_to(test_container, t => t.get_a<IGenericInterface<string>>()), target).Repeat.Once();
+ target.is_told_to(x => x.ValueReturningMethodWithAnArgument("blah")).it_will_return("hooray");
+ test_container.is_told_to(t => t.get_a<IGenericInterface<string>>()).it_will_return(target).Repeat.Once();
};
because b = () =>
trunk/product/MyMoney/Infrastructure/proxies/IProxyFactory.cs
@@ -1,13 +1,10 @@
using System;
-using System.Collections.Generic;
using Castle.Core.Interceptor;
namespace MoMoney.Infrastructure.proxies
{
public interface IProxyFactory
{
- TypeToProxy create_proxy_for<TypeToProxy>(TypeToProxy implementation, IEnumerable<IInterceptor> interceptors);
-
- TypeToProxy create_proxy_for<TypeToProxy>(Func<TypeToProxy> implementation, IEnumerable<IInterceptor> interceptors);
+ TypeToProxy create_proxy_for<TypeToProxy>(Func<TypeToProxy> implementation, params IInterceptor[] interceptors);
}
}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/proxies/ProxyBuilder.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using Castle.Core.Interceptor;
@@ -9,6 +10,7 @@ namespace MoMoney.Infrastructure.proxies
{
IConstraintSelector<TypeToProxy> add_interceptor<Interceptor>() where Interceptor : IInterceptor, new();
TypeToProxy create_proxy_for(TypeToProxy target);
+ TypeToProxy create_proxy_for(Func<TypeToProxy> target);
}
public class ProxyBuilder<TypeToProxy> : IProxyBuilder<TypeToProxy>
@@ -38,7 +40,12 @@ namespace MoMoney.Infrastructure.proxies
public TypeToProxy create_proxy_for(TypeToProxy target)
{
- return proxy_factory.create_proxy_for(()=>target, all_interceptors_with_their_constraints());
+ return create_proxy_for(() => target);
+ }
+
+ public TypeToProxy create_proxy_for(Func<TypeToProxy> target)
+ {
+ return proxy_factory.create_proxy_for(target, all_interceptors_with_their_constraints().ToArray());
}
IEnumerable<IInterceptor> all_interceptors_with_their_constraints()
trunk/product/MyMoney/Infrastructure/proxies/ProxyFactory.cs
@@ -20,21 +20,30 @@ namespace MoMoney.Infrastructure.proxies
this.generator = generator;
}
- public TypeToProxy create_proxy_for<TypeToProxy>(TypeToProxy implementation,
- IEnumerable<IInterceptor> interceptors)
+ public TypeToProxy create_proxy_for<TypeToProxy>(Func<TypeToProxy> implementation, params IInterceptor[] interceptors)
{
- return generator.CreateInterfaceProxyWithTarget<TypeToProxy>(implementation, interceptors.ToArray());
+ return create_proxy_for(lazy_load(implementation), interceptors);
}
- public TypeToProxy create_proxy_for<TypeToProxy>(Func<TypeToProxy> implementation, IEnumerable<IInterceptor> interceptors)
+ T lazy_load<T>(Func<T> implementation)
{
- var proxy = create_proxy_for<TypeToProxy>(() => new LazyLoadedInterceptor<TypeToProxy>(implementation));
- return create_proxy_for(proxy, interceptors);
+ if (typeof (T).IsInterface)
+ {
+ return generator.CreateInterfaceProxyWithoutTarget<T>(new LazyLoadedInterceptor<T>(implementation));
+ }
+ return generator.CreateClassProxy<T>(new LazyLoadedInterceptor<T>(implementation));
}
- static T create_proxy_for<T>(Func<IInterceptor> interceptor)
+ TypeToProxy create_proxy_for<TypeToProxy>(TypeToProxy implementation,
+ IEnumerable<IInterceptor> interceptors)
{
- return new ProxyGenerator().CreateInterfaceProxyWithoutTarget<T>(interceptor());
+ if (typeof (TypeToProxy).IsInterface)
+ {
+ return generator.CreateInterfaceProxyWithTarget<TypeToProxy>(implementation, interceptors.ToArray());
+ }
+ var list = interceptors.ToList();
+ list.Add(new LazyLoadedInterceptor<TypeToProxy>(() => implementation));
+ return generator.CreateClassProxy<TypeToProxy>(list.ToArray());
}
}
}
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/proxies/ProxyFactorySpecs.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Data;
+using Castle.Core.Interceptor;
+using jpboodhoo.bdd;
+using jpboodhoo.bdd.contexts;
+using jpboodhoo.bdd.mbunit;
+using MoMoney.Testing.MetaData;
+using MoMoney.Testing.spechelpers.contexts;
+
+namespace MoMoney.Infrastructure.proxies
+{
+ [Concern(typeof(ProxyFactory))]
+ public abstract class behaves_like_proxy_factory : concerns_for<IProxyFactory, ProxyFactory>
+ {
+ public override IProxyFactory create_sut()
+ {
+ return new ProxyFactory();
+ }
+ }
+
+ public class when_creating_a_proxy_with_a_target : behaves_like_proxy_factory
+ {
+ it should_forward_all_calls_to_the_target = () => target.was_told_to(x => x.Open());
+
+ it should_return_a_proxy_to_the_target = () =>
+ {
+ result.should_not_be_null();
+ result.GetType().should_not_be_equal_to(target.GetType());
+ };
+
+ it should_allow_the_interceptors_to_intercept_all_calls =
+ () => interceptor.recieved_call.should_be_true();
+
+ context c = () => { target = the_dependency<IDbConnection>(); };
+
+ because b = () =>
+ {
+ interceptor = new TestInterceptor();
+ result = sut.create_proxy_for(() => target, interceptor);
+ result.Open();
+ };
+
+ static IDbConnection target;
+ static IDbConnection result;
+ static TestInterceptor interceptor;
+ }
+
+ public class when_creating_a_proxy_of_a_target_but_a_call_has_not_been_made_to_the_proxy_yet :
+ behaves_like_proxy_factory
+ {
+ it should_not_create_an_instance_of_the_target = () => TestClass.was_created.should_be_false();
+
+ context c = TestClass.reset;
+
+ because b = () => { result = sut.create_proxy_for<IDisposable>(() => new TestClass()); };
+
+ after_each_observation ae = TestClass.reset;
+
+ static IDisposable result;
+ }
+
+ public class when_creating_a_proxy_of_a_component_that_does_not_implement_an_interface : behaves_like_proxy_factory
+ {
+ it should_return_a_proxy = () => result.should_not_be_null();
+
+ because b = () => { result = sut.create_proxy_for(() => new ClassWithNoInterface()); };
+
+ after_each_observation ae = TestClass.reset;
+
+ static ClassWithNoInterface result;
+ }
+
+ public class ClassWithNoInterface
+ {
+ }
+
+ public class TestClass : IDisposable
+ {
+ public static bool was_created;
+
+ public TestClass()
+ {
+ was_created = true;
+ }
+
+ public static void reset()
+ {
+ was_created = false;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+
+ public class TestInterceptor : IInterceptor
+ {
+ public bool recieved_call { get; set; }
+
+ public void Intercept(IInvocation invocation)
+ {
+ recieved_call = true;
+ invocation.Proceed();
+ }
+ }
+}
\ No newline at end of file
trunk/product/MyMoney/windows.ui/wire_up_the_views_in_to_the.cs
@@ -39,6 +39,7 @@ namespace MoMoney.windows.ui
register.transient<ICheckForUpdatesView, CheckForUpdatesView>();
register.transient<INotificationIconView, NotificationIconView>();
register.transient<IStatusBarView, StatusBarView>();
+ //register.proxy<IStatusBarView>(;
}
}
}
\ No newline at end of file
trunk/product/MyMoney/MyMoney.csproj
@@ -237,6 +237,7 @@
<Compile Include="Infrastructure\proxies\ProxyBuilder.cs" />
<Compile Include="Infrastructure\proxies\ProxyBuilderSpecs.cs" />
<Compile Include="Infrastructure\proxies\ProxyFactory.cs" />
+ <Compile Include="Infrastructure\proxies\ProxyFactorySpecs.cs" />
<Compile Include="Infrastructure\registries\default_registry.cs" />
<Compile Include="Infrastructure\registries\default_registry_specs.cs" />
<Compile Include="Domain\accounting\billing\Bill.cs" />