/// <inheritdoc /> protected override void RegisterTypes(IReadOnlyCollection <Type> types) { var registrationDetails = new RegistrationDetails(this.GetType()); foreach (var type in types ?? new Type[0]) { this.MutableRegisteredTypeToDetailsMap.Add(type, registrationDetails); } }
/// <summary> /// Run configuration logic. /// </summary> /// <param name="dependentConfigurationTypeToInstanceMap">Map of dependent configuration type to configured instance.</param> public virtual void Configure(IReadOnlyDictionary <Type, SerializationConfigurationBase> dependentConfigurationTypeToInstanceMap) { if (!this.configured) { lock (this.syncConfigure) { if (!this.configured) { // Configure dependency map. this.DependentConfigurationTypeToInstanceMap = dependentConfigurationTypeToInstanceMap; foreach (var dependentConfigurationTypeToInstance in dependentConfigurationTypeToInstanceMap) { var dependentConfigType = dependentConfigurationTypeToInstance.Key; var dependentConfigInstance = dependentConfigurationTypeToInstance.Value; var registrationDetails = new RegistrationDetails(dependentConfigType); var dependentConfigRegisteredTypes = dependentConfigInstance .RegisteredTypeToDetailsMap .Where(_ => _.Value.RegisteringType == dependentConfigType).ToList(); foreach (var dependentConfigRegisteredType in dependentConfigRegisteredTypes) { this.MutableRegisteredTypeToDetailsMap.Add( dependentConfigRegisteredType.Key, registrationDetails); } } // Save locals to work with. var localClassTypesToRegister = this.ClassTypesToRegister ?? new List <Type>(); var localInterfaceTypesToRegisterImplementationOf = this.InterfaceTypesToRegisterImplementationOf ?? new List <Type>(); var localTypesToAutoRegisterWithDiscovery = this.TypesToAutoRegisterWithDiscovery ?? new List <Type>(); var localTypesToAutoRegister = this.TypesToAutoRegister ?? new List <Type>(); var localClassTypesToRegisterAlongWithInheritors = this.ClassTypesToRegisterAlongWithInheritors ?? new List <Type>(); // Basic assertions. this.DependentConfigurationTypeToInstanceMap.Must().NotBeNull(); localInterfaceTypesToRegisterImplementationOf.Must().NotContainAnyNullElements(); localTypesToAutoRegisterWithDiscovery.Must().NotContainAnyNullElements(); localTypesToAutoRegister.Must().NotContainAnyNullElements(); localClassTypesToRegisterAlongWithInheritors.Must().NotContainAnyNullElements(); localClassTypesToRegisterAlongWithInheritors.Select(_ => _.IsClass).Named(Invariant($"{nameof(this.ClassTypesToRegisterAlongWithInheritors)}.Select(_ => _.{nameof(Type.IsClass)})")).Must().Each().BeTrue(); localInterfaceTypesToRegisterImplementationOf.Select(_ => _.IsInterface).Named(Invariant($"{nameof(this.InterfaceTypesToRegisterImplementationOf)}.Select(_ => _.{nameof(Type.IsInterface)})")).Must().Each().BeTrue(); // Run optional initial config for the last inheritor. this.InitialConfiguration(); // Run inheritor specific setup logic (like custom third party serializers/converters/resolvers). this.InternalConfigure(); // Accumulate all possible types from configuration. var discoveredTypes = this.DiscoverAllContainedAssignableTypes(localTypesToAutoRegisterWithDiscovery); var typesToAutoRegister = new Type[0] .Concat(localClassTypesToRegister) .Concat(localTypesToAutoRegister) .Concat(localInterfaceTypesToRegisterImplementationOf) .Concat(localClassTypesToRegisterAlongWithInheritors) .Concat(localTypesToAutoRegisterWithDiscovery) .Concat(discoveredTypes) .ToList(); var typesToAutoRegisterAlreadyHandledByDependentConfiguration = typesToAutoRegister.Intersect(this.RegisteredTypeToDetailsMap.Keys).ToList(); if (typesToAutoRegisterAlreadyHandledByDependentConfiguration.Any()) { // TODO: what info do we want to capture here? throw new DuplicateRegistrationException("Attempted to register types that are already registered", typesToAutoRegisterAlreadyHandledByDependentConfiguration); } var allTypesToRegister = DiscoverAllAssignableTypes(typesToAutoRegister) .Concat(discoveredTypes) .Distinct() .ToList(); // Register all types with inheritors to do additional configuration. this.RegisterTypes(allTypesToRegister); // Run optional final config for the last inheritor. this.FinalConfiguration(); this.configured = true; } } } }