public void ShouldGetInstanceTypeWithConstrains(Type type, Type targetType, Type expectedType) { // Given var dependency = new AutowiringDependency(type); // When var actualType = dependency.GetInstanceTypeBasedOnTargetGenericConstrains(targetType); // Then actualType.ShouldBe(expectedType); }
public bool TryBuildExpression(IBuildContext buildContext, ILifetime lifetime, out Expression expression, out Exception error) { var resolvedKey = _keyResolver(buildContext.Key); buildContext.CreateChild(resolvedKey, buildContext.Container); var type = resolvedKey.Type; var hasExpression = new AutowiringDependency(type, buildContext.AutowiringStrategy).TryBuildExpression(buildContext, lifetime, out expression, out error); if (_options.HasFlag(Options.ResolveArgs)) { var argsResolverType = ArgsResolverDescriptor.MakeGenericType(type).Descriptor(); var ctor = argsResolverType.GetDeclaredConstructors().Single(i => i.GetParameters().Length == 1); var resolverVar = Expression.Variable(argsResolverType.Type); var fallbackExpression = expression; if (!hasExpression) { if (_options.HasFlag(Options.ResolveDefaults) && type.Descriptor().IsValueType()) { fallbackExpression = Expression.Default(type); } else { fallbackExpression = Expression.Block( Expression.Throw( Expression.Constant( new InvalidOperationException($"Cannot find a dependency for {buildContext.Key} in {buildContext.Container}. Try passing an argument of corresponding type assignable to {type.GetShortName()} via one of a Func<> arguments..\n{buildContext}"))), Expression.Default(type)); } } expression = Expression.Block( new[] { resolverVar }, Expression.Assign(resolverVar, Expression.New(ctor, buildContext.ArgsParameter)), Expression.Condition( Expression.Field(resolverVar, nameof(ArgsResolver <object> .HasValue)), Expression.Field(resolverVar, nameof(ArgsResolver <object> .Value)), fallbackExpression) ); return(true); } if (_options.HasFlag(Options.ResolveDefaults) && type.Descriptor().IsValueType()) { expression = Expression.Default(type); error = default(Exception); return(true); } return(true); }