public CreationResult TryResolveDummyValue(Type typeOfDummy, LoopDetectingResolutionContext resolutionContext) { // Make sure we're not already resolving typeOfDummy. It may seem that we could skip this check when we have // a cached resolution strategy in strategyCache, but it's necessary in case multiple threads are involved and // typeOfDummy has a constructor that takes typeOfDummy as a parameter. // In that situation, perhaps this thread starts trying to resolve a Dummy using the constructor that takes a // typeOfDummy. Meanwhile another thread does the same thing, but gets more processing time and eventually fails to // use that constructor, but then it succeeds in making a typeOfDummy using a different constructor. Then the strategy // is cached. This thread sees the cached strategy, creates a typeOfDummy for the constructor parameter, and then // uses it to make the "outer" typeOfDummy. Then we'd have Dummies created via two different constructors, which // might have different behavior. This is essentially the problem that arose in issue 1639. if (!resolutionContext.TryBeginToResolve(typeOfDummy)) { return(CreationResult.FailedToCreateDummy(typeOfDummy, "Recursive dependency detected. Already resolving " + typeOfDummy + '.')); } try { return(this.strategyCache.TryGetValue(typeOfDummy, out ResolveStrategy cachedStrategy) ? cachedStrategy.TryCreateDummyValue(typeOfDummy, this, resolutionContext) : this.TryResolveDummyValueWithAllAvailableStrategies(typeOfDummy, resolutionContext)); } finally { resolutionContext.EndResolve(typeOfDummy); } }
private static IEnumerable <ResolvedArgument> ResolveArguments( IEnumerable <Type> parameterTypes, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { var resolvedArguments = new List <ResolvedArgument>(); foreach (var parameterType in parameterTypes) { var resolvedArgument = new ResolvedArgument(parameterType); try { var creationResult = resolver.TryResolveDummyValue(parameterType, resolutionContext); resolvedArgument.WasResolved = creationResult.WasSuccessful; if (creationResult.WasSuccessful) { resolvedArgument.ResolvedValue = creationResult.Result; } } catch { resolvedArgument.WasResolved = false; } resolvedArguments.Add(resolvedArgument); } return(resolvedArguments); }
public CreationResult CreateFake( Type typeOfFake, IProxyOptions proxyOptions, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (!CastleDynamicProxyGenerator.CanGenerateProxy(typeOfFake, out string?reasonCannotGenerate)) { return(CreationResult.FailedToCreateFake(typeOfFake, reasonCannotGenerate)); } if (proxyOptions.ArgumentsForConstructor is not null) { var proxyGeneratorResult = this.GenerateProxy(typeOfFake, proxyOptions, proxyOptions.ArgumentsForConstructor); return(proxyGeneratorResult.ProxyWasSuccessfullyGenerated ? CreationResult.SuccessfullyCreated(proxyGeneratorResult.GeneratedProxy) : CreationResult.FailedToCreateFake(typeOfFake, proxyGeneratorResult.ReasonForFailure !)); } return(this.TryCreateFakeWithDummyArgumentsForConstructor( typeOfFake, proxyOptions, resolver, resolutionContext)); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { return(this.creationResult); }
public ResolvedConstructor( IEnumerable <Type> parameterTypes, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { this.Arguments = ResolveArguments(parameterTypes, resolver, resolutionContext); }
public object CreateFake( Type typeOfFake, LoopDetectingResolutionContext resolutionContext) { var proxyOptions = this.BuildProxyOptions(typeOfFake, DefaultOptionsBuilder); return(this.fakeCreator.CreateFake(typeOfFake, proxyOptions, this.dummyValueResolver, resolutionContext).Result); }
private CreationResult TryCreateFakeWithDummyArgumentsForConstructor( Type typeOfFake, IProxyOptions proxyOptions, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { // Save the constructors as we try them. Avoids eager evaluation and double evaluation // of constructors enumerable. var consideredConstructors = new List <ResolvedConstructor>(); if (this.parameterTypesCache.TryGetValue(typeOfFake, out Type[]? cachedParameterTypes))
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { return(this.FakeCreator.CreateFakeWithoutLoopDetection( typeOfDummy, new ProxyOptions(), resolver, resolutionContext)); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { var success = this.DummyFactory.TryCreateDummyObject(typeOfDummy, out object result); return(success ? CreationResult.SuccessfullyCreated(result) : CreationResult.FailedToCreateDummy(typeOfDummy, "No Dummy Factory produced a result.")); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfDummy.GetTypeInfo().IsValueType&& typeOfDummy != typeof(void)) { return(CreationResult.SuccessfullyCreated(Activator.CreateInstance(typeOfDummy))); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a value type.")); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { var proxyOptions = this.ProxyOptionsFactory.BuildProxyOptions(typeOfDummy, null); return(this.FakeCreator.CreateFakeWithoutLoopDetection( typeOfDummy, proxyOptions, resolver, resolutionContext)); }
public bool TryCreateDummy(Type typeOfDummy, LoopDetectingResolutionContext resolutionContext, out object result) { var creationResult = this.dummyValueResolver.TryResolveDummyValue(typeOfDummy, resolutionContext); if (creationResult.WasSuccessful) { result = creationResult.Result; return(true); } result = default; return(false); }
public object CreateFake( Type typeOfFake, Action <IFakeOptions> optionsBuilder, LoopDetectingResolutionContext resolutionContext) { if (typeOfFake.IsValueType) { throw new FakeCreationException(ExceptionMessages.FailedToFakeValueType(typeOfFake)); } var proxyOptions = this.proxyOptionsFactory.BuildProxyOptions(typeOfFake, optionsBuilder); return(this.fakeCreator.CreateFake(typeOfFake, proxyOptions, this.dummyValueResolver, resolutionContext).Result !); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfDummy.GetTypeInfo().IsGenericType&& typeOfDummy.GetGenericTypeDefinition() == typeof(Lazy <>)) { var typeOfLazyResult = typeOfDummy.GetGenericArguments()[0]; var method = CreateLazyDummyGenericDefinition.MakeGenericMethod(typeOfLazyResult); var dummy = method.Invoke(null, new object[] { resolver }); return(CreationResult.SuccessfullyCreated(dummy)); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a Lazy.")); }
public CreationResult CreateFakeWithoutLoopDetection( Type typeOfFake, IProxyOptions proxyOptions, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfFake.IsInterface) { return(this.defaultCreationStrategy.CreateFakeInterface(typeOfFake, proxyOptions)); } return(DelegateCreationStrategy.IsResponsibleForCreating(typeOfFake) ? this.delegateCreationStrategy.CreateFake(typeOfFake, proxyOptions) : this.defaultCreationStrategy.CreateFake(typeOfFake, proxyOptions, resolver, resolutionContext)); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfDummy == typeof(Task)) { return(CreationResult.SuccessfullyCreated(TaskHelper.CompletedTask)); } if (typeOfDummy.IsGenericType && typeOfDummy.GetGenericTypeDefinition() == typeof(Task <>)) { var typeOfTaskResult = typeOfDummy.GetGenericArguments()[0]; var creationResult = resolver.TryResolveDummyValue(typeOfTaskResult, resolutionContext); object?taskResult = creationResult.WasSuccessful ? creationResult.Result : typeOfTaskResult.GetDefaultValue(); var method = GenericFromResultMethodDefinition.MakeGenericMethod(typeOfTaskResult); return(CreationResult.SuccessfullyCreated(method.Invoke(null, new[] { taskResult }))); } if (typeOfDummy.FullName == "System.Threading.Tasks.ValueTask") { return(CreationResult.SuccessfullyCreated(typeOfDummy.GetDefaultValue())); } if (typeOfDummy.IsGenericType && !typeOfDummy.IsGenericTypeDefinition && typeOfDummy.FullName is string fullName && fullName.StartsWith("System.Threading.Tasks.ValueTask`", StringComparison.Ordinal)) { var typeOfTaskResult = typeOfDummy.GetGenericArguments()[0]; var creationResult = resolver.TryResolveDummyValue(typeOfTaskResult, resolutionContext); object?taskResult = creationResult.WasSuccessful ? creationResult.Result : typeOfTaskResult.GetDefaultValue(); var ctor = typeOfDummy.GetConstructor(new[] { typeOfTaskResult }) !; return(CreationResult.SuccessfullyCreated(ctor.Invoke(new[] { taskResult }))); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a Task.")); }
public CreationResult TryResolveDummyValue(Type typeOfDummy, LoopDetectingResolutionContext resolutionContext) { if (this.strategyCache.TryGetValue(typeOfDummy, out ResolveStrategy cachedStrategy)) { return(cachedStrategy.TryCreateDummyValue(typeOfDummy, this, resolutionContext)); } if (!resolutionContext.TryBeginToResolve(typeOfDummy)) { return(CreationResult.FailedToCreateDummy(typeOfDummy, "Recursive dependency detected. Already resolving " + typeOfDummy + '.')); } var creationResult = this.TryResolveDummyValueWithAllAvailableStrategies(typeOfDummy, resolutionContext); if (creationResult.WasSuccessful) { resolutionContext.OnSuccessfulResolve(typeOfDummy); } return(creationResult); }
private CreationResult TryResolveDummyValueWithAllAvailableStrategies( Type typeOfDummy, LoopDetectingResolutionContext resolutionContext) { CreationResult creationResult = null; foreach (var strategy in this.strategies) { var thisCreationResult = strategy.TryCreateDummyValue(typeOfDummy, this, resolutionContext); if (thisCreationResult.WasSuccessful) { this.strategyCache.TryAdd(typeOfDummy, strategy); return(thisCreationResult); } creationResult = CreationResult.MergeIntoDummyResult(creationResult, thisCreationResult); } this.strategyCache.TryAdd(typeOfDummy, new UnableToResolveStrategy(creationResult)); return(creationResult); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfDummy.GetTypeInfo().IsGenericType&& typeOfDummy.GetGenericTypeDefinition() == typeof(Lazy <>)) { var typeOfLazyResult = typeOfDummy.GetGenericArguments()[0]; var creationResult = resolver.TryResolveDummyValue(typeOfLazyResult, resolutionContext); object lazyResult = creationResult.WasSuccessful ? creationResult.Result : typeOfLazyResult.GetDefaultValue(); var funcType = typeof(Func <>).MakeGenericType(typeOfLazyResult); var method = CreateGenericFromResultMethodDefinition().MakeGenericMethod(typeOfLazyResult); var func = method.Invoke(null, new[] { lazyResult }); var dummy = typeOfDummy.GetConstructor(new[] { funcType, typeof(bool) }).Invoke(new[] { func, true }); return(CreationResult.SuccessfullyCreated(dummy)); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a Lazy.")); }
public CreationResult CreateFake( Type typeOfFake, IProxyOptions proxyOptions, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (!resolutionContext.TryBeginToResolve(typeOfFake)) { return(CreationResult.FailedToCreateFake(typeOfFake, "Recursive dependency detected. Already resolving " + typeOfFake + '.')); } var result = this.CreateFakeWithoutLoopDetection( typeOfFake, proxyOptions, resolver, resolutionContext); if (result.WasSuccessful) { resolutionContext.OnSuccessfulResolve(typeOfFake); } return(result); }
public CreationResult CreateFake( Type typeOfFake, IProxyOptions proxyOptions, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (!resolutionContext.TryBeginToResolve(typeOfFake)) { return(CreationResult.FailedToCreateFake(typeOfFake, "Recursive dependency detected. Already resolving " + typeOfFake + '.')); } try { return(this.CreateFakeWithoutLoopDetection( typeOfFake, proxyOptions, resolver, resolutionContext)); } finally { resolutionContext.EndResolve(typeOfFake); } }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeOfDummy == typeof(Task)) { return(CreationResult.SuccessfullyCreated(TaskHelper.FromResult(default(object)))); } if (typeOfDummy.GetTypeInfo().IsGenericType&& typeOfDummy.GetGenericTypeDefinition() == typeof(Task <>)) { var typeOfTaskResult = typeOfDummy.GetGenericArguments()[0]; var creationResult = resolver.TryResolveDummyValue(typeOfTaskResult, resolutionContext); object taskResult = creationResult.WasSuccessful ? creationResult.Result : typeOfTaskResult.GetDefaultValue(); var method = GenericFromResultMethodDefinition.MakeGenericMethod(typeOfTaskResult); return(CreationResult.SuccessfullyCreated(method.Invoke(null, new[] { taskResult }))); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a Task.")); }
public object CreateDummy(Type typeOfDummy, LoopDetectingResolutionContext resolutionContext) { return(this.dummyValueResolver.TryResolveDummyValue(typeOfDummy, resolutionContext).Result); }
public override CreationResult TryCreateDummyValue(Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (IsTuple(typeOfDummy)) { var argTypes = typeOfDummy.GetTypeInfo().GetGenericArguments(); var args = new object[argTypes.Length]; for (int i = 0; i < argTypes.Length; i++) { var argType = argTypes[i]; var creationResult = resolver.TryResolveDummyValue(argType, resolutionContext); args[i] = creationResult.WasSuccessful ? creationResult.Result : argType.GetDefaultValue(); } var dummy = Activator.CreateInstance(typeOfDummy, args); return(CreationResult.SuccessfullyCreated(dummy)); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is not a tuple.")); }
public object CreateFake( Type typeOfFake, LoopDetectingResolutionContext resolutionContext) { return(this.CreateFake(typeOfFake, optionsBuilder: null !, resolutionContext)); }
public override CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext) { if (typeof(Delegate).IsAssignableFrom(typeOfDummy)) { return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is a Delegate.")); } if (typeOfDummy.GetTypeInfo().IsAbstract) { return(CreationResult.FailedToCreateDummy(typeOfDummy, "It is abstract.")); } // Save the constructors as we try them. Avoids eager evaluation and double evaluation // of constructors enumerable. var consideredConstructors = new List <ResolvedConstructor>(); if (this.cachedConstructors.TryGetValue(typeOfDummy, out ConstructorInfo cachedConstructor)) { var resolvedConstructor = new ResolvedConstructor( cachedConstructor.GetParameters().Select(pi => pi.ParameterType), resolver, resolutionContext); if (resolvedConstructor.WasSuccessfullyResolved) { if (TryCreateDummyValueUsingConstructor(cachedConstructor, resolvedConstructor, out object result)) { return(CreationResult.SuccessfullyCreated(result)); } consideredConstructors.Add(resolvedConstructor); } } else { foreach (var constructor in GetConstructorsInOrder(typeOfDummy)) { var resolvedConstructor = new ResolvedConstructor( constructor.GetParameters().Select(pi => pi.ParameterType), resolver, resolutionContext); if (resolvedConstructor.WasSuccessfullyResolved && TryCreateDummyValueUsingConstructor(constructor, resolvedConstructor, out object result)) { this.cachedConstructors[typeOfDummy] = constructor; return(CreationResult.SuccessfullyCreated(result)); } consideredConstructors.Add(resolvedConstructor); } } if (consideredConstructors.Any()) { return(CreationResult.FailedToCreateDummy(typeOfDummy, consideredConstructors)); } return(CreationResult.FailedToCreateDummy(typeOfDummy, "It has no public constructors.")); }
public abstract CreationResult TryCreateDummyValue( Type typeOfDummy, IDummyValueResolver resolver, LoopDetectingResolutionContext resolutionContext);