// This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext <FinanceDbContext>(options =>
                                                     options.UseInMemoryDatabase("FinanceDb"));

            services.AddRazorPages();
            services.AddServerSideBlazor();

            services = DependencyInjectionRegistration.Register(services);
        }
Example #2
0
        public void RegisterType(IServiceCollection serviceCollection, Type type)
        {
            if (!type.IsInterface)
            {
                if (type.IsClass && !type.IsAbstract)
                {
                    // Filter attributes to have only attributes for arbitrary environments and attributes fitting to the current environment.
                    var isEnvironmentCorrect = type.EvaluateDerivedCustomAttributePredicate <InjectionEnumRestrictionAttribute>(era => era.ValidEnumValues.Any(vev => _enumRestrictions.Any(ev => Equals(ev, vev))), trueIfEmpty: true);

                    var registrationAttributes = type.GetCustomDerivedAttribute <InjectionRegistrationAttribute>()
                                                 .OrderByDescending(i => i.RegisteredInterfaces.Count())
                                                 .ToList();

                    if (registrationAttributes.Any() && isEnvironmentCorrect)
                    {
                        var injectInListAttributes = type.GetSingleCustomAttribute <InjectInListAttribute>();
                        var alreadyRegisteredTypes = new HashSet <Type>();

                        foreach (var registrationAttribute in registrationAttributes)
                        {
                            IList <Type> interfaceTypes = registrationAttribute.RegisteredInterfaces;
                            if (interfaceTypes.Any())
                            {
                                var repeatedlyRegisteredTypes = interfaceTypes.Where(i => alreadyRegisteredTypes.Contains(i)).ToList();
                                if (repeatedlyRegisteredTypes.Any())
                                {
                                    throw new InjectionRegistrationException(repeatedlyRegisteredTypes.First(), type, $"Reflected interfaces [{string.Join( ", ", repeatedlyRegisteredTypes.Select( i => i.FullName ) )}] of {type.FullName} cannot be registered, since they were already registered for the same type with another attribute.");
                                }
                                //    if ( !registrationAttribute.RegisteredInterfaces.Contains( type ) ) {
                                //        interfaceTypes = new Type[ registrationAttribute.RegisteredInterfaces.Count() + 1 ];
                                //        interfaceTypes[ 0 ] = type;
                                //        registrationAttribute.RegisteredInterfaces.CopyTo( interfaceTypes, 1 );
                                //    } else {
                                //        interfaceTypes = registrationAttribute.RegisteredInterfaces;
                                //    }
                            }
                            else
                            {
                                interfaceTypes = type.GetInterfaces().Where(i => !alreadyRegisteredTypes.Contains(i)).ToList();
                                if (!interfaceTypes.Contains(type))
                                {
                                    interfaceTypes.Insert(0, type);
                                }
                                interfaceTypes = interfaceTypes.Where(i => !alreadyRegisteredTypes.Contains(i)).ToList();
                            }

                            var explicitOverriddenTypes = new HashSet <Type>(type.GetCustomAttribute <InjectionExplicitOverrideAttribute>().SelectMany(a => a.OverriddenTypes));
                            DependencyInjectionRegistration firstRegistration = null;

                            foreach (var interfaceType in interfaceTypes)
                            {
                                CheckInterfaceType(interfaceType, type);

                                // Selects the type to which the interface is mapped currently
                                var existingRegistration = _registrations.SingleOrDefault(i => i.RegisteredInterface == interfaceType);
                                if (existingRegistration != null && !type.IsSubclassOf(existingRegistration.RegisteredToType) && !explicitOverriddenTypes.Contains(existingRegistration.RegisteredToType))
                                {
                                    // Check whether this type was overridden explicitly
                                    var isExplicitlyOverridden = existingRegistration.RegisteredToType.EvaluateCustomAttributePredicate <InjectionExplicitOverrideAttribute>(eoa => eoa.OverriddenTypes.Any(t => t.Equals(type)));

                                    if (existingRegistration.RegisteredToType != type && !existingRegistration.RegisteredToType.IsSubclassOf(type) && !isExplicitlyOverridden)
                                    {
                                        // Only registrations of inherited types may be overwritten. An alternative branch to an already registered type may not be registered.
                                        throw new InjectionRegistrationException(interfaceType, type, $"Reflected interface {interfaceType.FullName} of {type.FullName} cannot be registered, since it is already registered to {existingRegistration.RegisteredToType.FullName}, which is not a superclass.");
                                    }
                                    if (firstRegistration == null)
                                    {
                                        firstRegistration = existingRegistration;
                                    }
                                }
                                else
                                {
                                    var registration = new DependencyInjectionRegistration {
                                        RegisteredInterface   = interfaceType,
                                        RegisteredToType      = type,
                                        UsedOtherRegistration = firstRegistration
                                    };
                                    _registrations.Add(registration);

                                    switch (registrationAttribute)
                                    {
                                    case InjectAsGlobalSingletonAttribute _:
                                        registration.Lifetime = ServiceLifetime.Singleton;
                                        if (firstRegistration == null)
                                        {
                                            serviceCollection.AddSingleton(interfaceType, type);
                                        }
                                        else
                                        {
                                            serviceCollection.AddSingleton(interfaceType, sp => sp.GetService(firstRegistration.RegisteredInterface));
                                        }
                                        break;

                                    case InjectAsRequestSingletonAttribute _:
                                        registration.Lifetime = ServiceLifetime.Scoped;
                                        if (firstRegistration == null)
                                        {
                                            serviceCollection.AddScoped(interfaceType, type);
                                        }
                                        else
                                        {
                                            serviceCollection.AddScoped(interfaceType, sp => sp.GetService(firstRegistration.RegisteredInterface));
                                        }
                                        break;

                                    case InjectAsNewInstanceAttribute _:
                                        registration.Lifetime = ServiceLifetime.Transient;
                                        if (firstRegistration == null)
                                        {
                                            serviceCollection.AddTransient(interfaceType, type);
                                        }
                                        else
                                        {
                                            serviceCollection.AddTransient(interfaceType, sp => sp.GetService(firstRegistration.RegisteredInterface));
                                        }
                                        break;

                                    default:
                                        // An implementation of IInjcetionScopeAttribute was given, but is not supported.
                                        throw new InjectionRegistrationException(interfaceType, type, $"Reflected interface {interfaceType.FullName} of {type.FullName} cannot be registered, since InjectionRegistrationAttribute was invalid.");
                                    }

                                    if (existingRegistration != null && (type.IsSubclassOf(existingRegistration.RegisteredToType) || explicitOverriddenTypes.Contains(existingRegistration.RegisteredToType)))
                                    {
                                        var existingRegistrationChildren = existingRegistration.UsedByOtherRegistrations.ToList();
                                        foreach (var existingRegistrationChild in existingRegistrationChildren)
                                        {
                                            CheckInterfaceType(existingRegistrationChild.RegisteredInterface, type);

                                            existingRegistrationChild.RegisteredToType      = type;
                                            existingRegistrationChild.UsedOtherRegistration = registration;
                                            registration.UsedByOtherRegistrations.Add(existingRegistrationChild);
                                        }
                                        _registrations.Remove(existingRegistration);
                                    }

                                    if (firstRegistration == null)
                                    {
                                        firstRegistration = registration;
                                    }
                                    else
                                    {
                                        firstRegistration.UsedByOtherRegistrations.Add(registration);
                                    }
                                }
                            }

                            if (injectInListAttributes.Count == 1)
                            {
                                var injectInListAttribute = injectInListAttributes.First();

                                var listInterfaceTypes = injectInListAttribute.RegisteredInterfaces;

                                if (!serviceCollection.Any(reg => reg.ServiceType == typeof(ListInjectionRegistrationManager)))
                                {
                                    serviceCollection.AddSingleton(_listInjectionRegistrationManager);
                                }

                                foreach (var interfaceType in listInterfaceTypes)
                                {
                                    CheckInterfaceType(interfaceType, type);

                                    _listInjectionRegistrationManager.RegisterTypeForListInterfaceType(type, interfaceType, injectInListAttribute.RemoveSubtypesFromList);

                                    var listInjectionType = typeof(IEnumerable <>).MakeGenericType(interfaceType);
                                    if (!serviceCollection.Any(reg => reg.ServiceType == listInjectionType))
                                    {
                                        var listInjectionProxyType = typeof(ListInjectionProxy <>).MakeGenericType(interfaceType);
                                        serviceCollection.AddTransient(listInjectionType, listInjectionProxyType);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        public static IHostBuilder CreateHostBuilder()
        {
            var hzConfiguration = new HazelcastConfig();
            var emailSettings   = new EmailSettings();

            return(new HostBuilder()
                   .ConfigureAppConfiguration((hostContext, configurationBuilder) =>
            {
                var configurationRoot = configurationBuilder
                                        .AddJsonFile("appsettings.json")
                                        .AddEnvironmentVariables()
                                        .Build();
                configurationRoot.Bind(nameof(HazelcastConfig), hzConfiguration);
                configurationRoot.Bind(nameof(EmailSettings), emailSettings);
            })
                   .ConfigureLogging(loggingBuilder =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.UseLog4Net(new FileInfo("log4net.config"));
            })
                   .ConfigureSimpleInjector()
                   .ConfigureContainer <Container>((hostBuilderContext, container) =>
            {
                container.RegisterSingleton(() => hzConfiguration);

                // Register IMessagingClientFactory
                container.RegisterSingleton <IMessagingClientFactory, HazelcastMessagingClientFactory>();

                // Register IMessagingClient
                container.RegisterSingleton(() =>
                {
                    var config = container.GetInstance <IConfiguration>();
                    var factory = container.GetInstance <IMessagingClientFactory>();
                    return factory.CreateClient(nameof(HazelcastConfig), config);
                });

                // Register IMessagePublisher
                container.RegisterSingleton <IMessagePublisher>(container.GetInstance <IMessagingClient>);

                // Register IMessageSubscriber
                container.RegisterSingleton <IMessageSubscriber>(container.GetInstance <IMessagingClient>);

                // Register data context
                container.RegisterSingleton(() => new OrganizationServiceDataContextFactory {
                    LoggerFactory = container.GetInstance <ILoggerFactory>()
                });

                //Register Email Service
                container.RegisterSingleton(() => new EmailService(emailSettings));

                container.RegisterScoped(() =>
                {
                    var factory = container.GetInstance <OrganizationServiceDataContextFactory>();
                    var connectionString = hostBuilderContext.Configuration.GetConnectionString(nameof(OrganizationServiceDataContext));
                    return factory.CreateDbContext(connectionString);
                });

                // Register repositories
                DependencyInjectionRegistration.RegisterRepositories(container);

                // Register services
                DependencyInjectionRegistration.RegisterServices(container);

                //Register subscribers
                DependencyInjectionRegistration.RegisterSubscribers(container);

                //Register healthchecks
                DependencyInjectionRegistration.RegisterHealthChecks(container);
            })
                   .AddGrpcService <ProfileController>()
                   .AddGrpcService <OrganizationController>()
                   .AddGrpcService <OrganizationUserController>()
                   .AddGrpcService <GroupController>()
                   .AddGrpcService <GroupAuthorizationController>()
                   .AddGrpcService <AuthorizationController>()
                   .AddGrpcService <UserInvitationController>()
                   .AddGrpcService <HealthController>()
                   .ConfigureGrpcServer(
                       Assembly.GetEntryAssembly().GetName().Name,
                       (hostBuilderContext) =>
            {
                var config = new TracingConfig();
                hostBuilderContext.Configuration.Bind(nameof(TracingConfig), config);
                return config;
            },
                       (hostBuilderContext, c, logger, serverServiceDefinitions, interceptors) =>
            {
                var server = new Server();
                var config = new GrpcConfig();

                hostBuilderContext.Configuration.Bind(nameof(GrpcConfig), config);

                server.Ports.Add(new ServerPort(config.Host, config.Port, ServerCredentials.Insecure));

                GrpcEnvironment.SetLogger(logger);

                serverServiceDefinitions
                .ToList()
                .ForEach(x => { server.Services.Add(x.Intercept(interceptors.ToArray())); });

                return server;
            })
                   .ConfigureContainer <Container>(container => container.Verify()));
        }