public static void AddCosmosContext <TContext>(this IServiceCollection services) where TContext : CosmosContext, new() { services.AddTransient(typeof(TContext), provider => { var cosmosDbClient = provider.GetRequiredService <ICosmosDbClient>(); var cosmosContext = new TContext(); Type cosmosContextType = typeof(TContext); // concrete repository type to instantiate against the IRepository<> interface Type repoType = typeof(CosmosDbContainerRepository <>); IEnumerable <PropertyInfo> contextRepositories = cosmosContextType.GetProperties() .Where(prop => prop.PropertyType.IsInterface && prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(IRepository <>)); foreach (PropertyInfo prop in contextRepositories) { Type repositoryEntityGenericType = prop.PropertyType.GetGenericArguments()[0]; Type constructedRepoType = repoType.MakeGenericType(repositoryEntityGenericType); // TODO: how can we allow multiple repos of the same type but with different names and pk paths? // We somehow have to search via ContainerDefs or... rework the whole config story...and have a Config() method on the CosmosContext that // we use to configure each repository individually... ContainerDefinition containerDefinition = cosmosDbClient.GetContainerDefinitionForType(prop.PropertyType.GetGenericArguments()[0]); ICosmosDbContainer container = cosmosDbClient.CreateContainer(containerDefinition).ConfigureAwait(false).GetAwaiter().GetResult(); var entityTypeNameResolverInstance = new CosmosDbEntityTypeNameResolver(); var pkvResolver = new CosmosDbPartitionKeyResolver(); var idValueGeneratorType = typeof(CosmosDbIdValueGenerator <>); var idValueGeneratorInstanceType = idValueGeneratorType.MakeGenericType(repositoryEntityGenericType); var idValueGeneratorInstance = Activator.CreateInstance(idValueGeneratorInstanceType); object repoInstance = Activator.CreateInstance(constructedRepoType, args: new object[] { container, entityTypeNameResolverInstance, idValueGeneratorInstance, pkvResolver }); prop.SetValue(cosmosContext, repoInstance); } return(cosmosContext); }); }
public static void AddCosmosDbContext <TContext>(this IServiceCollection services) where TContext : DbContext, new() { services.AddTransient(typeof(TContext), provider => { var cosmosDbClient = provider.GetRequiredService <ICosmosDbClient>(); var instance = new TContext(); Type instanceType = typeof(TContext); // concrete repository type to instantiate against the IRepository<> interface Type repoType = typeof(CosmosDbContainerRepository <>); IEnumerable <PropertyInfo> contextRepositories = instanceType.GetProperties() .Where(prop => prop.PropertyType.IsInterface && prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(IRepository <>)); var containerFactory = provider.GetRequiredService <ICosmosDbContainerFactory>(); foreach (PropertyInfo prop in contextRepositories) { Type repositoryEntityGenericType = prop.PropertyType.GetGenericArguments()[0]; Type constructedRepoType = repoType.MakeGenericType(repositoryEntityGenericType); ContainerDefinition containerDefinition = cosmosDbClient.GetContainerDefinitionForType(prop.PropertyType.GetGenericArguments()[0]); ICosmosDbContainer container = containerFactory.Create(instanceType, containerDefinition, cosmosDbClient); var entityTypeNameResolverInstance = new CosmosDbEntityTypeNameResolver(); var pkvResolver = new CosmosDbPartitionKeyResolver(); var idValueGeneratorType = typeof(CosmosDbIdValueGenerator <>); var idValueGeneratorInstanceType = idValueGeneratorType.MakeGenericType(repositoryEntityGenericType); var idValueGeneratorInstance = Activator.CreateInstance(idValueGeneratorInstanceType); object repoInstance = Activator.CreateInstance(constructedRepoType, args: new object[] { container, entityTypeNameResolverInstance, idValueGeneratorInstance, pkvResolver }); prop.SetValue(instance, repoInstance); } return(instance); }); }