/// <summary> /// Registers a service provider instance to be used for object resolution /// </summary> /// <param name="serviceProvider">The service provider to register</param> public void Register(AbstractServiceProvider serviceProvider) { if (serviceProvider is StaticServiceProvider) { StaticProviders.Add(serviceProvider.GetType(), serviceProvider as StaticServiceProvider); } else if (serviceProvider is ScopedServiceProvider) { this.ScopedProviders.Add(serviceProvider.GetType(), serviceProvider as ScopedServiceProvider); } else { throw new ArgumentException(WRONG_SERVICE_PROVIDER_MESSAGE); } this.AllProviders.Add(serviceProvider.GetType(), serviceProvider); }
/// <summary> /// Whitelists a list of assemblies through the Reflection TypeFactory and then grabs all types and attempts to register any types that are relevant to the /// engine /// </summary> static Engine() { StaticLogger.Log($"Penguin.DependencyInjection: {Assembly.GetExecutingAssembly().GetName().Version}", StaticLogger.LoggingLevel.Call); ChildDependencies = new ConcurrentDictionary <Type, List <PropertyInfo> >(); Registrations = new ConcurrentDictionary <Type, ConcurrentList <Registration> >(); foreach (Type t in TypeFactory.GetAllTypes()) { try { if (t.IsAbstract || t.IsInterface) { continue; } foreach (DependencyRegistrationAttribute autoReg in t.GetCustomAttributes <DependencyRegistrationAttribute>()) { if (autoReg is RegisterAttribute ra) { if (ra.RegisteredTypes.Length > 0) { foreach (Type registeredType in ra.RegisteredTypes) { Register(registeredType, t, null, StaticServiceRegister.GetServiceProvider(ra.Lifetime)); } } else { Register(t, t, null, StaticServiceRegister.GetServiceProvider(ra.Lifetime)); } } else if (autoReg is RegisterThroughMostDerivedAttribute rmd) { RegisterAllBaseTypes(rmd.RequestType, TypeFactory.GetMostDerivedType(t), StaticServiceRegister.GetServiceProvider(rmd.Lifetime)); } } if (t.ImplementsInterface <IRegisterDependencies>()) { StaticLogger.Log($"DependencyInjector: Registering {nameof(IRegisterDependencies)} of type {t.FullName} from assembly {t.Assembly.FullName}", StaticLogger.LoggingLevel.Call); (Activator.CreateInstance(t) as IRegisterDependencies).RegisterDependencies(Registrar); } if (t.ImplementsInterface(typeof(IConsolidateDependencies <>))) { foreach (Type type in t.GetClosedImplementationsFor(typeof(IConsolidateDependencies <>))) { dependencyConsolidators.TryAdd(type.GetGenericArguments()[0], t); } } if (t.ImplementsInterface <ISelfRegistering>()) { Register(t, t, typeof(TransientServiceProvider)); } if (t.IsSubclassOf(typeof(StaticServiceProvider))) { StaticServiceProvider provider = Activator.CreateInstance(t) as StaticServiceProvider; StaticProviders.Add(t, provider); } } catch (Exception ex) { StaticLogger.Log("Failed to load information for type: " + t.FullName, StaticLogger.LoggingLevel.Call); StaticLogger.Log(ex.StackTrace, StaticLogger.LoggingLevel.Call); StaticLogger.Log(ex.Message, StaticLogger.LoggingLevel.Call); } } }