Skip to content

Commit e9885d7

Browse files
authored
Merge pull request #288 from microsoft/adr_dynamic_data_sources
ADR Dynamic DataSource Registration
2 parents dde4970 + ac62673 commit e9885d7

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# 0014. Dynamic Data Source Registration
2+
3+
## Status
4+
5+
Proposed
6+
7+
## Context
8+
9+
Decouple the data sources from the SDK into their own NuGet packages will allow for new data sources to be plugged in with minimum configuration and dependency on the existing code base.
10+
11+
## Decision
12+
13+
- Decoupling from SDK
14+
15+
Each data source can be built externally with no dependency on the CarbonAware SDK. This helps achieve single responsibility principle and makes the system extensible.
16+
17+
- Increased Maintainability
18+
19+
Currently, the data source registration code is implemented using a switch statement to register the appropriate data source based on configuration. This can be removed completely and only the data source needed can be imported into the SDK.
20+
21+
- Controlled Solution Size
22+
23+
All the data sources are part of the current SDK, even if they are not used at runtime. For e.g., if both **IEmissions** and **IForecast** interfaces are configured to use WattTime, we need not package the JSON and ElectricityMaps data sources, thereby reducing solution’s size.
24+
25+
- Reduction of Security threats
26+
27+
Having decoupled data sources as packages, it allows us to control potential security threats that can be injected into the overall system, by providing the opportunity to certify them.
28+
29+
## Consequences
30+
31+
Be able to have outsourced Data Sources would benefit the overall system in case there is a large number of those by allowing which one should be part of a solution.
32+
33+
## Design Considerations
34+
35+
Currently Data Sources project is consumed by GSF library using Dependency Injection. Each GSF library handlers have references to `IForecastDataSource` and/or `IEmissionsDataSource` Data Source interfaces.
36+
To modify this interaction and to make it more dynamic, these are things that required to be considered:
37+
38+
- Public interfaces & Data Records
39+
40+
Data Sources interfaces and Data Records are internal and available only to certain projects (i.e GSF.CarbonAware). This would require to be changed so consumers can dynamically register those and consume them.
41+
42+
Effort Level: **Medium**
43+
44+
- Packaging
45+
46+
Current Data Source project is not allowed to be packaged (NuGet package, see `<IsPackable>` property on one of the Data Source projects), which would require how this is going to be done in terms of, what the package contains, versioning and where to publish it.
47+
48+
Effort Level: **Medium**
49+
50+
- Load, Register and Instantiate
51+
52+
Using techniques like **Reflection** and **Assembly Discovery**, it would be possible to load Data Sources assemblies and instantiate classes that implements the interfaces that are available.
53+
As an example, this could be done via a Data Source class loader
54+
55+
```c#
56+
static Assembly[] GetDataSourceAssemblies()
57+
{
58+
var assemblies = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
59+
.Where(x => x.Contains("CarbonAware.DataSource"))
60+
.Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x)));
61+
return assemblies.ToArray();
62+
}
63+
```
64+
65+
Then the consumer could be using Reflection to instantiate the classes interested:
66+
67+
```c#
68+
Type providerType = DataSourceAssembly.GetType("CarbonAware.DataSource.ProviderA");
69+
70+
var theForecast = Activator.CreateInstance(providerType) as IForecastDataSource;
71+
theForecast.GetCarbonIntensityForecastAsync(…) // Invoke the interface method.
72+
```
73+
74+
This responsibility should be part of a new GSF library subsystem.
75+
76+
Effort Level: **Medium**
77+
78+
- Data Source manifest
79+
80+
Configuration information would be required to be part of the Data Source package, so the GSF handlers can interact with it. Properties like where to locate the assembly, what assembly to load, what classes to interact with (i.e., Builders/Factories) therefore Emissions and Forecast data can be retrieved from GSF handlers. Designing this manifest would help to drive the implementation of the other items.
81+
82+
Effort Level: **Large**
83+
84+
- GSF Enhancements
85+
86+
Given the fact the current registration is done using Dependency Injection, GSF library would require to be changed and enhanced to accommodate discovery, how to load the assemblies that are available and that implement Data Sources interfaces. Also understand the configuration that comes from the manifest, in such a way that all the required properties are available.
87+
88+
Effort Level: **Medium**
89+
90+
- Documentation
91+
92+
Document how to create 3rd party Data Sources, how to package them and how to configure those based on a Data Source manifest.
93+
94+
Effort Level: **Medium**
95+
96+
## Green Impact
97+
98+
Positive
99+
100+
## References
101+
102+
[Package dotnet CLI](https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package-dotnet-cli)
103+
104+
[Sign Package](https://learn.microsoft.com/en-us/nuget/create-packages/sign-a-package)
105+
106+
[Assemblies in .NET](https://learn.microsoft.com/en-us/dotnet/standard/assembly/)

0 commit comments

Comments
 (0)