1

I'm developing an Android app whose architecture is based on the well known Uncle's Bob Clean Architecture.

I have the following Use Case:

Validate User Subscription

It's based on this use case descryption( main success scenario)

  1. Check if validation warning was already shown

    • Yes -> Go to step 6

    • No -> Go to step 2

  2. Check if user has internet connection

    • Yes -> Access remote repository

    • No -> Access local repository

  3. System gets user's subscription hash in repository

  4. System generates a key to decrypt the subscription hash

  5. System decrypts the hash using the previously generated key and returns the status of the subscription ( Valid / Invalid)

    • Status is valid: System saves the subscription on device and changes the user type to Premium

    • Status is invalid: System saves the subscription on device changes the user type to Free

  6. Use case terminates

I'm facing a problem on step 2. As you can see, I need to change my repository during the use case execution, but I don't know the best way to implement it.

One of my ideas was to inject the repository through method injection ( using some sort of setRepository(Repository repository) instead of constructor injection. Is this ok?

  • 1
    What do you mean by "OK?" Note: don't answer that question with a tautology like "best practice." State a specific, objectively-answerable criteria. – Robert Harvey Nov 5 '16 at 18:57
  • Well, on the majority of examples about Clean Architecture that I saw/read the use case dependencies were injected during use case construction and not execution. Also, in my view I think that letting the use case choose the repository at execution time is bad for testing since the decision of which repository to use is inside the use case. – Rômulo.Edu Nov 5 '16 at 20:39
  • 4
    Why not inject a factory instead that will return the repository you need by passing it either 'local' or 'remote' as constructing arg ? – Steve Chamaillard Nov 7 '16 at 5:24
1

Try a proxy which has the remote and local repository as dependencies and use the one needed. Here is a C# implementation

public class ProxyRepository : IRepository

{
    private readonly IRepository _remoteRepository;
    private readonly IRepository _localRepository;

    public ProxyRepository(IRepository remoteRepository, IRepository localRepository)
    {
        _remoteRepository = remoteRepository;
        _localRepository = localRepository;
    }

    public byte[] GetUserHash(Guid userId)
    {
         if (ThereIsAnInternetConnection())
              return _remoteRepository.GetUserHash(userId);
         else
              return _localRepository.GetUserHash(userId);
    }

    private bool ThereIsAnInternetConnection()
    {
        // your implementation of this, you might want to cache this call
    }
}
  • 1
    In "clean architecture speak", this means moving the internet access check out of the Use Case and into a Gateway/Driver. This may or may not be OK, depending on if you consider "use the remote repository if there is internet access, the local repository otherwise" a business rule or not. – Jory Geerts Nov 7 '16 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.