6

I'm new to flutter/dart and I'm trying to create a little application using a Clean Architecture design. I read some blogs and several presentations of Uncle Bob's Clean Architecture before starting to code to get the most of it and now it's time to implement it.

I guess my application could be divided in 3 main features :

  • authentication
  • classes (get access to lessons/quizzes on specific subjects)
  • admin (manage user, create lessons etc..)

I started to implement the authentication feature following the clean pattern, that's to say with a domain, data and presentation layer and I guess I did it quite well. It's (almost) fully tested (I'm trying to do some TDD) and seems to work as I wanted.

Now comes the problem. I want to implement the classes feature. I wish it could be independent of the authentication but it's not the case... The classes feature need to get the authenticated user from the authentication feature. I searched a lot on the internet but I can't find how to implement Clean Architecture with multiple features that need to share some data.

So there are my 2 questions:

  • How to pass data from a feature to another ?
  • How to inject dependency in a feature that need data from another feature ? (I used get_it for the authentication feature and inject all dependencies in the main() method before building the app. Since it did not need any external data it worked well. Now it's seem not possible to do the same for the classes feature since it first needs to get some data from the authentication feature).

Thanks in advance for your answers.

4 Answers4

3

Along with your 3 features you should add another called core and inside that folder you can add stuffs that need to be shared. It worked for me . Good luck

2

One option is if you instantiate classes after the user has already logged in, you can pass that data in as a constructor parameter.

More generally, Provider is probably the best dependency injection tool for flutter. If you "provide" the authentication class to the widget tree for the rest of the app, you can say at any point below it, Provider.of(context) to access it and any public field it has.

Kris
  • 3,091
  • 20
  • 28
  • Thank you for taking the time to answer (and sorry for my late response). I guess there is not a unique solution and the one you proposed worked for me quite good eventhough I still find the authentication and classes features are to much coupled. – Baptiste Oueriagli Feb 13 '20 at 21:53
0

Hope you're still working on Flutter projects after that long time.

I've been fiddling around with Uncle Bob's Clean architecture, and I managed to implement it in Flutter few months ago.

It's perfect, it separates your code into components (modules if you're coming from a native Android development environment) and isolates your data sources, so if you want to change the way you make API requests for example, you'll only need to change the remote data source part in your app, and all your application should work as expected.

I have made a test app using Clean Architecture I just uploaded on github and added a humble readme that describes the basic architecture and components of the app, I'll work on written articles describing the code very soon.

For now you can access the repo from here

Taha Malas
  • 200
  • 2
  • 12
  • 1
    Hi thank you for you response. Unfortunately I already read all the stuff in your git repo (the majority of it coming directly from Reso Coder) and my question was not how to implement a unique feature but how to deal when multiple features need to share some data. – Baptiste Oueriagli Feb 13 '20 at 21:55
  • Yes that's true, the majority of the code coming from reso coder, I added some base classes to the architecture such as base local data source, base remote datasource and base repository, can you please describe with an example how you want to share data between multiple features – Taha Malas Feb 14 '20 at 10:54
  • In the initial post I made I described an example of such a case. The authentication feature is in charge of logging the user in but the classes feature then need to access it. That's this link of dependcy (classes needs data from authentication) that I'm struggling to abstract in a 'clean' way. – Baptiste Oueriagli Feb 14 '20 at 21:25
  • So for me the thing you're trying to achieve is this, you logged in using some feature, then in the repository you should be dealing with a local datasource to store the user token or some data for him, and that's can be achieved with local database or shared preferences, then when you need to make an API call or retrieve the user authentication you can make another feature which is "GetAuthenticatedUser" or anything to deal with the local datasource and retrieve the user's data – Taha Malas Feb 15 '20 at 01:01
0

I'm trying to find an answer to this for some time now... My solution was to create some transformation methods in the model class. For example, I have an ProductModel in the home feature file (from where i can add products to the cart), and an ProductInOrderHistoryModel in the order history feature file. So in the ProductInOrderHistoryModel file I have a method called toProductModel that gets an instance of ProductInOrderHistoryModel and transform to a ProductModel. That way I can add a product to the cart directly from my history order page. Probably it's not the best solution, and the Uncle Bom would be really mad at me. But it was how I manage to solve my problem...