Planned Technical Debt
This page collects planned technical debt items, so that we'll be able to address them all in one go when we do it.
1. Logging
In v22 / v23 we plan to move logging to Microsoft.Extensions.Logging.
2. Dependency Injection
- Dependency Injection of exotic context information (Page, ExecutionContext, etc.)
3. Nullable Projects
- Make the DNN project nullable
- Make the Oqtane project nullable
4. Composition over Inheritance
We have a lot of inheritance built into the system, and this causes a lot of difficulties following code and making changes without introducing unintended side effects.
We should aim to refactor the system to favor composition over inheritance wherever possible.
4.1. How to find problematic inheritance
- Look for classes that inherit from
ServiceBase<T>but not fromDataSourceBase- probably exporting both lists to text and then filter - Look for classes that inherit from
ServiceBaseindirectly
4.2. How to Refactor
TODO
4.2.1. Option 1:Create a Helper for Shared Logic
When refactoring inheritance to composition, identify the logic that is shared across multiple classes and extract it into a helper class or service. This allows the shared functionality to be reused without relying on a common base class.
This helper can be
- injected
- called by the implementation
Example (conceptual, not code):
Suppose multiple classes need to perform logging.
Instead of having them inherit from a common base class that provides logging functionality,
you can create a LoggingHelper class that encapsulates the logging logic.
Each class can then either have the LoggingHelper injected or call it directly to perform logging.
4.2.2. Option 2: Use Providers
Another approach to refactoring inheritance to composition is to use providers. Providers encapsulate specific functionality and can be injected into classes that need them. This allows classes to delegate responsibilities to providers instead of relying on a common base class.
For example, if multiple classes need to access configuration settings,
you can create a ConfigurationProvider and inject it into the classes that require it.
So a core service would be the main service (like an ExportService)
but it would use an ExportConfigProvider which is specific to the implementation.
4.3. Candidates
AppsCacheBase@STV- Things inheriting from
AdamWorkBase - Things inheriting from
SerializerBase Eav.DataSources.AppandAppDataWithCrudAppBase<SxcAppBase.Dependencies>QueryandTypedQueryBlockEditorBaseand...Entity,...Module- Various
...Providersincl.SitesDataSourceProvider(DnnSitesDsProvider)AdamDataSourceProvider... CodeApiServiceBaseand derived types- maybe
ExecutionContext- but not sure ConvertToEavLightand derivedUiContextBuilderBaseand derived typesAdamSecurityChecksBaseand derived types
Note: Non-candidates are:
- Things derived from
DataSourceBase