public static ScimServerConfiguration WithTypeDefinitions(this ScimServerConfiguration serverConfiguration) { var compositionContainer = new CompositionContainer( new AggregateCatalog( new AssemblyCatalog(Assembly.GetExecutingAssembly()), new AssemblyCatalog(Assembly.GetAssembly(typeof(ScimServerConfiguration))), new AssemblyCatalog(Assembly.GetAssembly(typeof(ScimUser2))))); // discover and register all type definitions var owinScimAssembly = Assembly.GetExecutingAssembly(); var typeDefinitions = compositionContainer.GetExportTypesThatImplement<IScimTypeDefinition>(); foreach (var typeDefinition in typeDefinitions) { Type distinctTypeDefinition; var typeDefinitionTarget = GetTargetDefinitionType(typeDefinition); // the type of object being defined (e.g. User, Group, Name) if (serverConfiguration.TypeDefinitionRegistry.TryGetValue(typeDefinitionTarget, out distinctTypeDefinition)) { // already have a definition registered for the target type // let's favor non-Owin.Scim definitions over built-in defaults if (distinctTypeDefinition.Assembly == owinScimAssembly && typeDefinition.Assembly != owinScimAssembly) serverConfiguration.TypeDefinitionRegistry[typeDefinitionTarget] = typeDefinition; continue; } // register type definition serverConfiguration.TypeDefinitionRegistry[typeDefinitionTarget] = typeDefinition; } var enumerator = serverConfiguration.TypeDefinitionRegistry.Values.GetEnumerator(); while (enumerator.MoveNext()) { // creating type definitions may be expensive due to reflection // when a type definition is instantiated, it may implicitly instantiate/register other type // definitions for complex attributes, therefore, no need to re-create the same definition more than once if (serverConfiguration.ContainsTypeDefinition(enumerator.Current)) continue; var typeDefinition = (IScimTypeDefinition)enumerator.Current.CreateInstance(serverConfiguration); serverConfiguration.AddTypeDefiniton(typeDefinition); } return serverConfiguration; }