/// <summary> /// Helper method use to differentiate behavior between request handlers and notification /// handlers. Request handlers should only be added once (so set addIfAlreadyExists to false) /// Notification handlers should all be added (set addIfAlreadyExists to true) /// </summary> /// <param name="serviceRegistrar"> </param> /// <param name="registrationScope"> </param> /// <param name="openRequestInterface"> </param> /// <param name="assembliesToScan"> </param> /// <param name="addIfAlreadyExists"> </param> private static IServiceRegistrar ConnectImplementationsToTypesClosing(this IServiceRegistrar serviceRegistrar, RegistrationScope registrationScope, Type openRequestInterface, IEnumerable <Assembly> assembliesToScan, bool addIfAlreadyExists) { if (!assembliesToScan.Any()) { assembliesToScan = AppDomain.CurrentDomain.GetAssemblies(); } var concretions = new List <Type>(); var interfaces = new List <Type>(); foreach (var type in assembliesToScan.SelectMany(a => a.DefinedTypes).Where(t => !t.IsOpenGeneric())) { var interfaceTypes = Enumerable.ToArray <Type>(type.FindInterfacesThatClose(openRequestInterface)); if (!interfaceTypes.Any()) { continue; } if (type.IsConcrete()) { concretions.Add(type); } foreach (var interfaceType in interfaceTypes) { interfaces.Fill(interfaceType); } } foreach (var @interface in interfaces) { var exactMatches = concretions.Where(x => x.CanBeCastTo(@interface)).ToList(); if (addIfAlreadyExists) { foreach (var type in exactMatches) { serviceRegistrar.Register(@interface, type, registrationScope); } } else { if (exactMatches.Count > 1) { exactMatches.RemoveAll(m => !IsMatchingWithInterface(m, @interface)); } foreach (var type in exactMatches) { serviceRegistrar.Register(@interface, type, registrationScope); } } if ([email protected]()) { serviceRegistrar.AddConcretionsThatCouldBeClosed(registrationScope, @interface, concretions); } } return(serviceRegistrar); }