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); } }
public override CreationResult TryCreateDummyValue(Type typeOfDummy, IDummyValueResolver resolver) { 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(DummyCreationSession session, Type typeOfDummy) { 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), session, this.Resolver); 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), session, this.Resolver); 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 override CreationResult TryCreateDummyValue(Type typeOfDummy, IDummyValueResolver resolver) { 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) { 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 TryResolveDummyValue(DummyCreationSession session, Type typeOfDummy) { if (!session.TryBeginToResolveType(typeOfDummy)) { return(CreationResult.FailedToCreateDummy(typeOfDummy, "Recursive dependency detected. Already resolving " + typeOfDummy + '.')); } var creationResult = this.TryResolveDummyValueWithAllAvailableStrategies(session, typeOfDummy); if (creationResult.WasSuccessful) { session.OnSuccessfulResolve(typeOfDummy); } return(creationResult); }
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 override CreationResult TryCreateDummyValue(Type typeOfDummy, IDummyValueResolver resolver) { if (typeOfDummy.GetTypeInfo().IsGenericType&& typeOfDummy.GetGenericTypeDefinition() == typeof(Lazy <>)) { var typeOfLazyResult = typeOfDummy.GetGenericArguments()[0]; var creationResult = resolver.TryResolveDummyValue(typeOfLazyResult); 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 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); }
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 override CreationResult TryCreateDummyValue(Type typeOfDummy, IDummyValueResolver resolver) { 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); 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.")); }