using System; using System.Collections.Generic; using VContainer.Internal; namespace VContainer { public class RegistrationBuilder { protected internal readonly Type ImplementationType; protected internal readonly Lifetime Lifetime; protected internal List InterfaceTypes; protected internal List Parameters; public RegistrationBuilder(Type implementationType, Lifetime lifetime) { ImplementationType = implementationType; Lifetime = lifetime; } public virtual Registration Build() { var injector = InjectorCache.GetOrBuild(ImplementationType); var spawner = new InstanceProvider(injector, Parameters); return new Registration( ImplementationType, Lifetime, InterfaceTypes, spawner); } public RegistrationBuilder As() => As(typeof(TInterface)); public RegistrationBuilder As() => As(typeof(TInterface1), typeof(TInterface2)); public RegistrationBuilder As() => As(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3)); public RegistrationBuilder As() => As(typeof(TInterface1), typeof(TInterface2), typeof(TInterface3), typeof(TInterface4)); public RegistrationBuilder AsSelf() { AddInterfaceType(ImplementationType); return this; } public virtual RegistrationBuilder AsImplementedInterfaces() { InterfaceTypes = InterfaceTypes ?? new List(); InterfaceTypes.AddRange(ImplementationType.GetInterfaces()); return this; } public RegistrationBuilder As(Type interfaceType) { AddInterfaceType(interfaceType); return this; } public RegistrationBuilder As(Type interfaceType1, Type interfaceType2) { AddInterfaceType(interfaceType1); AddInterfaceType(interfaceType2); return this; } public RegistrationBuilder As(Type interfaceType1, Type interfaceType2, Type interfaceType3) { AddInterfaceType(interfaceType1); AddInterfaceType(interfaceType2); AddInterfaceType(interfaceType3); return this; } public RegistrationBuilder As(params Type[] interfaceTypes) { foreach (var interfaceType in interfaceTypes) { AddInterfaceType(interfaceType); } return this; } public RegistrationBuilder WithParameter(string name, object value) { Parameters = Parameters ?? new List(); Parameters.Add(new NamedParameter(name, value)); return this; } public RegistrationBuilder WithParameter(string name, Func value) { Parameters = Parameters ?? new List(); Parameters.Add(new FuncNamedParameter(name, value)); return this; } public RegistrationBuilder WithParameter(Type type, object value) { Parameters = Parameters ?? new List(); Parameters.Add(new TypedParameter(type, value)); return this; } public RegistrationBuilder WithParameter(Type type, Func value) { Parameters = Parameters ?? new List(); Parameters.Add(new FuncTypedParameter(type, value)); return this; } public RegistrationBuilder WithParameter(TParam value) { return WithParameter(typeof(TParam), value); } public RegistrationBuilder WithParameter(Func value) { return WithParameter(typeof(TParam), resolver => value(resolver)); } public RegistrationBuilder WithParameter(Func value) { return WithParameter(typeof(TParam), _ => value()); } protected virtual void AddInterfaceType(Type interfaceType) { if (!interfaceType.IsAssignableFrom(ImplementationType)) { throw new VContainerException(interfaceType, $"{ImplementationType} is not assignable from {interfaceType}"); } InterfaceTypes = InterfaceTypes ?? new List(); if (!InterfaceTypes.Contains(interfaceType)) InterfaceTypes.Add(interfaceType); } } }