Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make managing project dependencies more consistent #6158

Merged
merged 20 commits into from
Jul 15, 2024

Conversation

seadowg
Copy link
Member

@seadowg seadowg commented May 28, 2024

The idea here is to create a consistent way to create project level dependencies in objects that interact with multiple projects (like data services) to make it easier to write tests and to create ways of providing those dependencies.

This approach isn't completely finished. I've established the pattern, but some of our "providers" and their usages (like StoragePathProvider) would need significant rework and the main thing I wanted to get to here was a route forward. In those cases I've deprecated previous ways of access dependencies so we can remove them gradually.

I've also added some helpers for data services so we can keep the implementation more consistent in the form of new extensions for AppState.

Why is this the best possible solution? Were any other approaches considered?

I did initially look at using Dagger's "assisted injection", but I found this wasn't ideal. For instance, I'd end up with factories like this:

@AssistedFactory
public interface FormsRepositoryFactory {
  DatabaseFormsRepository create(ProjectsDataService projectDataService);
}

There are two problems here:

  1. DatabaseFormsRepository needs to have a constructor that knows about projects which we're trying to avoid.
  2. The factory has to explicitly declare the implementation type rather than an interface which makes it awkward to use in tests.

Given all that, I settled for a similar concept (injecting factories with a standard pattern for dependencies that need runtime info), but just hand make the factories instead of relying on Dagger injection.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

Do we need any specific form for testing your changes? If so, please attach one.

There's been a bunch of changes across the code base, but I think the main thing to check is that forms, instances and other pieces of data show up in the correct project.

Before submitting this PR, please make sure you have:

  • added or modified tests for any new or changed behavior
  • run ./gradlew connectedAndroidTest (or ./gradlew testLab) and confirmed all checks still pass
  • added a comment above any new strings describing it for translators
  • added any new strings with date formatting to DateFormatsTest
  • verified that any code or assets from external sources are properly credited in comments and/or in the about file.
  • verified that any new UI elements use theme colors. UI Components Style guidelines

@seadowg seadowg force-pushed the dependency-provider branch 7 times, most recently from 928c96d to f2b977b Compare June 3, 2024 12:59
@seadowg
Copy link
Member Author

seadowg commented Jun 11, 2024

I think it'd also be good to introduce a new convenience abstraction for building data services here. Something like:

abstract class DataService(private val appState: AppState) {

    fun <T> getData(key: String, default: T): Data<T> {
        return Data(appState, key, default)
    }
}

class Data<T>(private val appState: AppState, private val key: String, private val default: T) {
    fun get(qualifier: String? = null): Flow<T> {
        return appState.getFlow("$qualifier:$key", default)
    }

    fun set(value: T, qualifier: String? = null) {
        appState.setFlow("$qualifier:$key", value)
    }
}

@seadowg seadowg force-pushed the dependency-provider branch 2 times, most recently from f02e968 to e82ded5 Compare June 24, 2024 15:33
@seadowg
Copy link
Member Author

seadowg commented Jun 25, 2024

@grzesiek2010 we probably want to wait on merging this until we've got the last release things in, but I'd like to get your initial thoughts.

@seadowg seadowg marked this pull request as ready for review June 25, 2024 16:54
@grzesiek2010 grzesiek2010 merged commit 6786cb7 into getodk:master Jul 15, 2024
6 checks passed
@seadowg seadowg deleted the dependency-provider branch July 15, 2024 15:45
@dbemke
Copy link

dbemke commented Jul 17, 2024

Tested with Success!

Verified on a device with Android 10

Verified Cases:

  • sending, finalizing, saving forms as draft
  • deleting forms
  • adding duplicate projects
  • adding different versions of a form
  • regression checks in savepoints
  • manually copying instances of a form to a project
  • shortcuts
  • testers intents app

@WKobus
Copy link

WKobus commented Jul 17, 2024

Tested with Success!

Verified on a device with Android 14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants