Skip to content

Commit 723003d

Browse files
authored
Refactoring configuration handling. (#36)
Use dependency injection to inject configuration. This reduces complexity of configuration reading and initialization. The code mainly utilizes existing Configuration framework provided by .NET. We now have object corresponds to field in json file directly. * Refactoring Config provider to use framework to initialize the provider. * Rename DatabaseConnection to DataGatewayConfig * Rename class and variable to add "config" suffix * Fix code format and static analysis error. * Refactor test code to use static constructor. * Remove BuildServiceProvider * Use IOptions to access settings instead of direct settings object. * Fix incorrect merge conflict. * Reorder using headers * Fix formatting. * Set default value for ResolverConfigFile.
1 parent 02342a8 commit 723003d

File tree

10 files changed

+131
-139
lines changed

10 files changed

+131
-139
lines changed

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service.Tests/MetadataProviderTests.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ public class MetadataProviderTests
1010

1111
public MetadataProviderTests()
1212
{
13-
TestHelper.LoadConfig();
14-
_fileProvider = new FileMetadataStoreProvider();
13+
_fileProvider = new FileMetadataStoreProvider(TestHelper.DataGatewayConfig);
1514
}
1615

1716
[TestMethod]

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service.Tests/TestBase.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public TestBase()
2727

2828
private void Init()
2929
{
30-
TestHelper.LoadConfig();
31-
_clientProvider = new CosmosClientProvider();
30+
_clientProvider = new CosmosClientProvider(TestHelper.DataGatewayConfig);
3231
string uid = Guid.NewGuid().ToString();
3332
dynamic sourceItem = TestHelper.GetItem(uid);
3433

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service.Tests/TestHelper.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
using System;
12
using System.IO;
23
using Cosmos.GraphQL.Service.Models;
3-
using Newtonsoft.Json;
4+
using Cosmos.GraphQL.Service.configurations;
45
using Microsoft.Extensions.Configuration;
6+
using Microsoft.Extensions.Options;
7+
using Newtonsoft.Json;
58

69
namespace Cosmos.GraphQL.Service.Tests
710
{
@@ -48,17 +51,24 @@ public static MutationResolver SampleMutationResolver()
4851
return JsonConvert.DeserializeObject<MutationResolver>(raw);
4952
}
5053

51-
public static void LoadConfig()
54+
private static Lazy<IOptions<DataGatewayConfig>> _dataGatewayConfig = new Lazy<IOptions<DataGatewayConfig>>(() => TestHelper.LoadConfig());
55+
56+
private static IOptions<DataGatewayConfig> LoadConfig()
5257
{
53-
if (configurations.ConfigurationProvider.Initialized())
54-
{
55-
return;
56-
}
57-
var config = new ConfigurationBuilder()
58+
DataGatewayConfig datagatewayConfig = new DataGatewayConfig();
59+
IConfigurationRoot config = new ConfigurationBuilder()
5860
.SetBasePath(Directory.GetCurrentDirectory())
5961
.AddJsonFile("appsettings.Test.json")
6062
.Build();
61-
configurations.ConfigurationProvider.init(config);
63+
64+
config.Bind("DatabaseConnection", datagatewayConfig);
65+
66+
return Options.Create(datagatewayConfig);
67+
}
68+
69+
public static IOptions<DataGatewayConfig> DataGatewayConfig
70+
{
71+
get { return _dataGatewayConfig.Value; }
6272
}
6373

6474
public static object GetItem(string id)

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Resolvers/CosmosClientProvider.cs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,21 @@
11
using Cosmos.GraphQL.Service.configurations;
22
using Microsoft.Azure.Cosmos;
33
using Microsoft.Azure.Cosmos.Fluent;
4+
using Microsoft.Extensions.Options;
45

56
namespace Cosmos.GraphQL.Service.Resolvers
67
{
78
public class CosmosClientProvider
89
{
910
private static CosmosClient _cosmosClient;
10-
private static readonly object syncLock = new object();
1111

12-
private static void init()
12+
public CosmosClientProvider(IOptions<DataGatewayConfig> dataGatewayConfig)
1313
{
14-
var connectionString = ConfigurationProvider.getInstance().ConnectionString;
15-
_cosmosClient = new CosmosClientBuilder(connectionString).WithContentResponseOnWrite(true).Build();
14+
_cosmosClient = new CosmosClientBuilder(dataGatewayConfig.Value.Credentials.ConnectionString).WithContentResponseOnWrite(true).Build();
1615
}
1716

1817
public CosmosClient GetClient()
1918
{
20-
return getCosmosClient();
21-
}
22-
23-
public CosmosClient getCosmosClient()
24-
{
25-
if (_cosmosClient == null)
26-
{
27-
lock (syncLock)
28-
{
29-
if (_cosmosClient == null)
30-
{
31-
init();
32-
}
33-
}
34-
}
35-
3619
return _cosmosClient;
3720
}
3821
}

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Resolvers/CosmosQueryEngine.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public async Task<JsonDocument> ExecuteAsync(string graphQLQueryName, IDictionar
4444
// TODO: add support for TOP and Order-by push-down
4545

4646
var resolver = this._metadataStoreProvider.GetQueryResolver(graphQLQueryName);
47-
var container = this._clientProvider.getCosmosClient().GetDatabase(resolver.databaseName).GetContainer(resolver.containerName);
47+
var container = this._clientProvider.GetClient().GetDatabase(resolver.databaseName).GetContainer(resolver.containerName);
4848
var querySpec = new QueryDefinition(resolver.parametrizedQuery);
4949

5050
if (parameters != null)
@@ -78,7 +78,7 @@ public async Task<IEnumerable<JsonDocument>> ExecuteListAsync(string graphQLQuer
7878
// TODO: add support for TOP and Order-by push-down
7979

8080
var resolver = this._metadataStoreProvider.GetQueryResolver(graphQLQueryName);
81-
var container = this._clientProvider.getCosmosClient().GetDatabase(resolver.databaseName).GetContainer(resolver.containerName);
81+
var container = this._clientProvider.GetClient().GetDatabase(resolver.databaseName).GetContainer(resolver.containerName);
8282
var querySpec = new QueryDefinition(resolver.parametrizedQuery);
8383

8484
if (parameters != null)

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Resolvers/QueryExecutor.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Data.Common;
44
using System.Threading.Tasks;
55
using Cosmos.GraphQL.Service.configurations;
6+
using Microsoft.Extensions.Options;
67

78
namespace Cosmos.GraphQL.Service.Resolvers
89
{
@@ -12,6 +13,13 @@ namespace Cosmos.GraphQL.Service.Resolvers
1213
public class QueryExecutor<ConnectionT> : IQueryExecutor
1314
where ConnectionT : DbConnection, new()
1415
{
16+
private readonly DataGatewayConfig _datagatewayConfig;
17+
18+
public QueryExecutor(IOptions<DataGatewayConfig> dataGatewayConfig)
19+
{
20+
_datagatewayConfig = dataGatewayConfig.Value;
21+
}
22+
1523
/// <summary>
1624
/// Executes sql text that return result set.
1725
/// </summary>
@@ -21,7 +29,7 @@ public class QueryExecutor<ConnectionT> : IQueryExecutor
2129
public async Task<DbDataReader> ExecuteQueryAsync(string sqltext, IDictionary<string, object> parameters)
2230
{
2331
var conn = new ConnectionT();
24-
conn.ConnectionString = ConfigurationProvider.getInstance().ConnectionString;
32+
conn.ConnectionString = _datagatewayConfig.Credentials.ConnectionString;
2533
await conn.OpenAsync();
2634
DbCommand cmd = conn.CreateCommand();
2735
cmd.CommandText = sqltext;

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Services/FileMetadataStoreProvider.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.IO;
66
using System.Text.Json;
77
using System.Collections.Generic;
8+
using Microsoft.Extensions.Options;
89

910
namespace Cosmos.GraphQL.Service
1011
{
@@ -23,15 +24,18 @@ public class FileMetadataStoreProvider : IMetadataStoreProvider
2324
/// </summary>
2425
private IDictionary<string, string> _resolvers;
2526

26-
public FileMetadataStoreProvider()
27+
private readonly DataGatewayConfig _dataGatewayConfig;
28+
29+
public FileMetadataStoreProvider(IOptions<DataGatewayConfig> dataGatewayConfig)
2730
{
31+
_dataGatewayConfig = dataGatewayConfig.Value;
2832
init();
2933
}
3034

3135
private void init()
3236
{
3337
string jsonString = File.ReadAllText(
34-
ConfigurationProvider.getInstance().ResolverConfigFile);
38+
_dataGatewayConfig.ResolverConfigFile);
3539

3640
using (JsonDocument document = JsonDocument.Parse(jsonString))
3741
{

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Services/GraphQLService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ public class GraphQLService
1616
private readonly IMutationEngine _mutationEngine;
1717
private IMetadataStoreProvider _metadataStoreProvider;
1818

19-
public GraphQLService(IQueryEngine queryEngine, IMutationEngine mutationEngine, IMetadataStoreProvider metadataStoreProvider)
19+
public GraphQLService(IQueryEngine queryEngine,
20+
IMutationEngine mutationEngine,
21+
IMetadataStoreProvider metadataStoreProvider)
2022
{
2123
_queryEngine = queryEngine;
2224
_mutationEngine = mutationEngine;

Cosmos.GraphQL.Service/Cosmos.GraphQL.Service/Startup.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using Microsoft.Extensions.Hosting;
1010
using Microsoft.Data.SqlClient;
1111
using Npgsql;
12+
using Microsoft.Extensions.Options;
13+
using Microsoft.Extensions.DependencyInjection.Extensions;
1214

1315
namespace Cosmos.GraphQL.Service
1416
{
@@ -24,11 +26,16 @@ public Startup(IConfiguration configuration)
2426
// This method gets called by the runtime. Use this method to add services to the container.
2527
public void ConfigureServices(IServiceCollection services)
2628
{
27-
configurations.ConfigurationProvider.init(Configuration);
29+
services.Configure<DataGatewayConfig>(Configuration.GetSection("DatabaseConnection"));
30+
services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<DataGatewayConfig>, DataGatewayConfigPostConfiguration>());
31+
services.TryAddEnumerable(ServiceDescriptor.Singleton<IValidateOptions<DataGatewayConfig>, DataGatewayConfigValidation>());
2832

29-
DatabaseType dbType = configurations.ConfigurationProvider.getInstance().DbType;
33+
// Read configuration and use it locally.
34+
DataGatewayConfig dataGatewayConfig = new DataGatewayConfig();
35+
// Need to rename DatabaseConnection to DataGatewayConfig in the CI pipeline.
36+
Configuration.Bind("DatabaseConnection", dataGatewayConfig);
3037

31-
switch (dbType)
38+
switch (dataGatewayConfig.DatabaseType)
3239
{
3340
case DatabaseType.Cosmos:
3441
services.AddSingleton<CosmosClientProvider, CosmosClientProvider>();
@@ -52,7 +59,7 @@ public void ConfigureServices(IServiceCollection services)
5259
break;
5360
default:
5461
throw new NotSupportedException(String.Format("The provided DatabaseType value: {0} is currently not supported." +
55-
"Please check the configuration file.", dbType));
62+
"Please check the configuration file.", dataGatewayConfig.DatabaseType));
5663
}
5764

5865
services.AddSingleton<GraphQLService, GraphQLService>();

0 commit comments

Comments
 (0)