public void Register(ContanerRegistrationContext context) { ICReg reg; var possibleConstructors = _constructorTrait.ReturnPossibleConstructors(_implementationType).ToList(); var bestConstructor = _constructorTrait.ChooseConstructor(_implementationType, possibleConstructors); if (bestConstructor == null) { throw new ArgumentException($"Cannot find public constructor for {_implementationType.FullName}"); } switch (_liveScopeTrait.Lifetime) { case Lifetime.AlwaysNew: reg = new AlwaysNewImpl(_implementationType, bestConstructor); break; case Lifetime.Singleton: reg = new SingletonImpl(_implementationType, new AlwaysNewImpl(_implementationType, bestConstructor), context.SingletonCount); context.SingletonCount++; break; default: throw new ArgumentOutOfRangeException(); } context.AddCReg(_asTrait.GetAsTypesFor(_implementationType), _asTrait.PreserveExistingDefaults, reg); }
public ICRegILGen?ResolveNeedBy(Type type, object?key) { if (_container.Registrations.TryGetValue(new KeyAndType(key, type), out var registration)) { if (registration is ICRegMulti multi) { registration = ChooseFromMulti(multi, false) ?? multi.ChosenOne; } } if (registration == null) { if (type.IsDelegate()) { var resultType = type.GetMethod("Invoke") !.ReturnType; var nestedRegistration = ResolveNeedBy(resultType, key); if (nestedRegistration == null) { return(null); } registration = new DelegateImpl(key, type, nestedRegistration); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Lazy <>)) { var resultType = type.GetGenericArguments()[0]; var nestedRegistration = ResolveNeedBy(resultType, key); if (nestedRegistration == null) { return(null); } registration = new LazyImpl(type, nestedRegistration); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { var resultType = type.GetGenericArguments()[0]; var child = MakeEnumEnabledChild(); var nestedRegistration = child.ResolveNeedBy(resultType, key); if (nestedRegistration == null) { if (key != null) { return(null); } registration = new EmptyEnumerableImpl(type, resultType); } else { registration = new EnumerableImpl(key, type, resultType, child, nestedRegistration); } } else if (type.IsArray && type.GetArrayRank() == 1) { var resultType = type.GetElementType(); var child = MakeEnumEnabledChild(); var nestedRegistration = child.ResolveNeedBy(resultType !, key); if (nestedRegistration == null) { return(null); } registration = new EnumerableImpl(key, type, resultType, child, nestedRegistration); } else if (type.IsGenericType && TupleTypes.Contains(type.GetGenericTypeDefinition())) { registration = new AlwaysNewImpl(type, type.GetConstructors()[0], false); } } if (registration != null) { if (registration is ICRegILGen result) { return(result); } throw new ArgumentException("Builder for " + type.ToSimpleName() + " is not ILGen capable"); } return(null); }