SubstitutionContext() { var callRouterFactory = new CallRouterFactory(); var argSpecificationQueue = new ArgumentSpecificationDequeue(DequeueAllArgumentSpecifications); var dynamicProxyFactory = new CastleDynamicProxyFactory(argSpecificationQueue); var delegateFactory = new DelegateProxyFactory(argSpecificationQueue); var proxyFactory = new ProxyFactory(delegateFactory, dynamicProxyFactory); var callRouteResolver = new CallRouterResolver(); _substituteFactory = new SubstituteFactory(this, callRouterFactory, proxyFactory, callRouteResolver); }
public void SupportMixins(CastleDynamicProxyFactory factory) { const string expectedName = "any string"; var dummyMixin = new List <object> { new DummyMixin { Name = expectedName } }; var proxy = factory.ExtendClass <DummyTab>(Enumerable.Empty <IAlternateMethod>(), dummyMixin); Assert.NotNull(proxy); Assert.NotNull(proxy as ITab); var mixin = proxy as IDummyMixin; Assert.NotNull(mixin); Assert.Equal(expectedName, mixin.Name); }
public void ExtendClassCreatesTrueProxy(ILogger logger, IMessageBroker messageBroker) { var timer = new ExecutionTimer(Stopwatch.StartNew()); var sut = new CastleDynamicProxyFactory(logger, messageBroker, () => timer, () => RuntimePolicy.On); var overrideMeAlternate = new OverrideMeAlternateMethod <TestProxy>(); var protectedOverrideMeAlternate = new ProtectedOverrideMeAlternateMethod <TestProxy>(); var methodInvocations = new List <IAlternateMethod> { overrideMeAlternate, protectedOverrideMeAlternate }; var result = sut.ExtendClass <TestProxy>(methodInvocations); result.OverrideMe(); Assert.Equal(1, overrideMeAlternate.HitCount); Assert.Equal(1, protectedOverrideMeAlternate.HitCount); Assert.Equal(1, result.HitCountOverrideMe); Assert.Equal(1, result.HitCountProtectedOverrideMe); }
public void WrapInterfaceCreatesWrappingProxy(ILogger logger, IMessageBroker messageBroker) { var timer = new ExecutionTimer(Stopwatch.StartNew()); var sut = new CastleDynamicProxyFactory(logger, messageBroker, () => timer, () => RuntimePolicy.On); var overrideMeAlternate = new OverrideMeAlternateMethod <ITestProxy>(); var methodInvocations = new List <IAlternateMethod> { overrideMeAlternate }; var target = new TestProxy(); var result = sut.WrapInterface <ITestProxy>(target, methodInvocations); result.OverrideMe(); Assert.Equal(1, overrideMeAlternate.HitCount); Assert.Equal(1, result.HitCountOverrideMe); Assert.Equal(1, result.HitCountProtectedOverrideMe); Assert.Equal(1, target.HitCountOverrideMe); Assert.Equal(1, target.HitCountProtectedOverrideMe); }
private SubstitutionContext() { ThreadContext = new ThreadLocalContext(); var callSpecificationFactory = CallSpecificationFactoryFactoryYesThatsRight.CreateCallSpecFactory(); _callRouterResolver = new CallRouterResolver(); RouteFactory = new RouteFactory(ThreadContext, callSpecificationFactory); var sequenceNumberGenerator = new SequenceNumberGenerator(); var callInfoFactory = new CallInfoFactory(); var autoValueProvidersFactory = new AutoValueProvidersFactory(); var substituteStateFactory = new SubstituteStateFactory(sequenceNumberGenerator, callSpecificationFactory, callInfoFactory, autoValueProvidersFactory); var callRouterFactory = new CallRouterFactory(ThreadContext, RouteFactory); var argSpecificationQueue = new ArgumentSpecificationDequeue(ThreadContext.DequeueAllArgumentSpecifications); var dynamicProxyFactory = new CastleDynamicProxyFactory(argSpecificationQueue); var delegateFactory = new DelegateProxyFactory(dynamicProxyFactory); var proxyFactory = new ProxyFactory(delegateFactory, dynamicProxyFactory); SubstituteFactory = new SubstituteFactory(substituteStateFactory, callRouterFactory, proxyFactory); #pragma warning disable 618 // Obsolete SequenceNumberGenerator = sequenceNumberGenerator; #pragma warning restore 618 // Obsolete }
public DelegateProxyFactory(CastleDynamicProxyFactory objectProxyFactory) { _castleObjectProxyFactory = objectProxyFactory ?? throw new ArgumentNullException(nameof(objectProxyFactory)); }
object IProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, object[] constructorArguments) { // TODO: // * new type MockCtorPlaceholder in elevated assy // * generate new empty ctor that takes MockCtorPlaceholder in all mocked types // * support ctor params. throw if foudn and not ForPartsOf. then ForPartsOf determines which ctor we use. // * have a note about static ctors. because they are special, and do not support disposal, can't really mock them right. // best for user to do mock/unmock of static ctors manually (i.e. move into StaticInit/StaticDispose and call directly from test code) object proxy; var substituteConfig = ElevatedSubstitutionContext.TryGetSubstituteConfig(callRouter); if (typeToProxy.IsInterface || substituteConfig == null) { proxy = m_DefaultProxyFactory.GenerateProxy(callRouter, typeToProxy, additionalInterfaces, constructorArguments); } else if (typeToProxy == typeof(SubstituteStatic.Proxy)) { if (additionalInterfaces?.Any() == true) { throw new SubstituteException("Cannot substitute interfaces as static"); } if (constructorArguments.Length != 1) { throw new SubstituteException("Unexpected use of SubstituteStatic.For"); } // the type we want comes from SubstituteStatic.For as a single ctor arg var actualType = (Type)constructorArguments[0]; proxy = CreateStaticProxy(actualType, callRouter); } else { // requests for additional interfaces on patched types cannot be done at runtime. elevated mocking can't, // by definition, go through a runtime dynamic proxy generator that could add such things. if (additionalInterfaces.Any()) { throw new SubstituteException("Cannot add interfaces at runtime to patched types"); } switch (substituteConfig) { // TODO: i misunderstood "override all" and "call base", so fix these // need to store the yes/no flag with the router in the value of the dict and use that when routing for return to TryMock case SubstituteConfig.OverrideAllCalls: // overriding all calls includes the ctor, so it makes no sense for the user to pass in ctor args if (constructorArguments != null && constructorArguments.Any()) { throw new SubstituteException("Do not pass ctor args when substituting with elevated mocks (or did you mean to use ForPartsOf?)"); } // but we use a ctor arg to select the special empty ctor that we patched in //$$$ TODO constructorArguments = k_MockedCtorParams; break; case SubstituteConfig.CallBaseByDefault: // TODO: this is just wrong var castleDynamicProxyFactory = new CastleDynamicProxyFactory(); return(castleDynamicProxyFactory.GenerateProxy(callRouter, typeToProxy, additionalInterfaces, constructorArguments)); default: throw new ArgumentOutOfRangeException(); } proxy = Activator.CreateInstance(typeToProxy, constructorArguments); m_Routers.Add(proxy, callRouter); } return(proxy); }
public DelegateProxyFactory(CastleDynamicProxyFactory objectProxyFactory) { _castleObjectProxyFactory = objectProxyFactory; }
object IProxyFactory.GenerateProxy(ICallRouter callRouter, Type typeToProxy, Type[] additionalInterfaces, object[] constructorArguments) { // TODO: // * new type MockCtorPlaceholder in elevated assy // * generate new empty ctor that takes MockCtorPlaceholder in all mocked types // * support ctor params. throw if foudn and not ForPartsOf. then ForPartsOf determines which ctor we use. // * have a note about static ctors. because they are special, and do not support disposal, can't really mock them right. // best for user to do mock/unmock of static ctors manually (i.e. move into StaticInit/StaticDispose and call directly from test code) object proxy; var substituteConfig = ElevatedSubstitutionContext.TryGetSubstituteConfig(callRouter); if (typeToProxy.IsInterface || substituteConfig == null) { proxy = m_DefaultProxyFactory.GenerateProxy(callRouter, typeToProxy, additionalInterfaces, constructorArguments); } else if (typeToProxy == typeof(SubstituteStatic.Proxy)) { if (additionalInterfaces?.Any() == true) { throw new SubstituteException("Cannot substitute interfaces as static"); } if (constructorArguments.Length != 1) { throw new SubstituteException("Unexpected use of SubstituteStatic.For"); } // the type we want comes from SubstituteStatic.For as a single ctor arg var actualType = (Type)constructorArguments[0]; proxy = CreateStaticProxy(actualType, callRouter); } else { // requests for additional interfaces on patched types cannot be done at runtime. elevated mocking can't, // by definition, go through a runtime dynamic proxy generator that could add such things. if (additionalInterfaces.Any()) { throw new SubstituteException("Cannot add interfaces at runtime to patched types"); } switch (substituteConfig) { case SubstituteConfig.OverrideAllCalls: // overriding all calls includes the ctor, so it makes no sense for the user to pass in ctor args if (constructorArguments != null && constructorArguments.Any()) { throw new SubstituteException("Do not pass ctor args when substituting with elevated mocks (or did you mean to use ForPartsOf?)"); } // but we use a ctor arg to select the special empty ctor that we patched in constructorArguments = k_MockedCtorParams; break; case SubstituteConfig.CallBaseByDefault: var castleDynamicProxyFactory = new CastleDynamicProxyFactory(); return(castleDynamicProxyFactory.GenerateProxy(callRouter, typeToProxy, additionalInterfaces, constructorArguments)); case null: break; default: throw new ArgumentOutOfRangeException(); } // var proxyWrap = Activator.CreateInstanceFrom(patchAllDependentAssemblies[1].Path, typeToProxy.FullName, false, // BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance, null, // constructorArguments, null, null); // proxy = proxyWrap.Unwrap(); proxy = Activator.CreateInstance(typeToProxy, constructorArguments); GetRouterField(proxy.GetType()).SetValue(proxy, callRouter); } return(proxy); }