flutterando / clean-dart Goto Github PK
View Code? Open in Web Editor NEWProposta de Arquitetura Limpa para o Dart/Flutter
License: Apache License 2.0
Proposta de Arquitetura Limpa para o Dart/Flutter
License: Apache License 2.0
The section Application Business Rules in the last sentence states, that:
If a use case needs to access a higher layer, it should be done with the Dependency Inversion Principle in mind.
Shouldn't it be read as "...to access a lower layer..."? (Lower i.e. outer)
Tenho uma série de sugestões de melhorias no português do texto do README. Por favor, me adicionem como colaborador para que eu possa abrir o PR.
In Presenter there's a couple of duplicate sentences.
...API.w If we take...
Hi.
sorry me for my questions.
because I don't know Portuguese, I can't watch your videos, and this is the source of questions.
what is :
scripts:
mobx_build: $clean & $get & $runner build --delete-conflicting-outputs
mobx_watch: $clean & $get & $runner watch --delete-conflicting-outputs
what I did was to define some similar commands via aliases into my bash and use them,
but I don't know what is scripts
in pubspec
.
thanks
Hi, I would like to suggest the clean-dart-github project to add to the references of this documentation.
Some features of this project:
Flutter 3
Clean-Dart
architecture and applying it in different State Managers approachesUnit tests
with Mockito for Domain, Infra, External layersHi.
what I will do in my apps is to defining an ENV
interface and some implementations for that by specifying the flavor via Injectable
package.
as I can see in examples, there are some .env
files, it is the first time that I have seen these files,
can I ask that which one do you prefer to use ?
Thanks
I think adding some lint
rules, can make the examples much more valuable.
Thanks
@Injectable()
class SearchMobx = _SearchMobxBase with _$SearchMobx;
abstract class _SearchMobxBase with Store {
final SearchByText searchByText;
late CancelableOperation cancelableOperation;
Future stateReaction(String text,
[CancelableOperation? cancelableOperation]) async {
await cancelableOperation?.cancel();
cancelableOperation =
CancelableOperation<SearchState>.fromFuture(makeSearch(text));
if (text.isEmpty) {
setState(const StartState());
return;
}
setState(const LoadingState());
setState(
await cancelableOperation.valueOrCancellation(const LoadingState()));
}
_SearchMobxBase(this.searchByText) {
reaction((_) => searchText, (String text) async {
stateReaction(text, cancelableOperation);
}, delay: 500);
}
Future<SearchState> makeSearch(String text) async {
var result = await searchByText(text);
return result.fold((l) => ErrorState(l), (r) => SuccessState(r));
}
@observable
String searchText = '';
@observable
SearchState state = const StartState();
@action
setSearchText(String value) => searchText = value;
@action
setState(SearchState value) => state = value;
}
class SearchMobxPage extends StatefulWidget {
const SearchMobxPage({Key? key}) : super(key: key);
@override
_SearchMobxPageState createState() => _SearchMobxPageState();
}
class _SearchMobxPageState extends ModularState<SearchMobxPage, SearchMobx> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Github Search - MobX"),
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8, right: 8, left: 8),
child: TextField(
onChanged: controller.setSearchText,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "Pesquise...",
),
),
),
Expanded(
child: Observer(builder: (_) {
var state = controller.state;
if (state is ErrorState) {
return buildError(state.error);
}
if (state is StartState) {
return const Center(
child: Text('Digita alguma coisa...'),
);
} else if (state is LoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (state is SuccessState) {
return buildList(state.list);
} else {
return Container();
}
}),
)
],
),
);
}
}
Hi.
thanks to your nice repo,
in my usecase, I have to implement an AudioService
, the way I have implement it is:
1- define an interface in domain
2- implement it in infra
3- use it as a dependency to a cubit into my presentation layer and then, in my view, I used the cubit only.
the questions are:
1- as you said, we have External
layer and I think my implementation is wrong and I think that I have to put the implementation in External
layer rather than infra
.
2- it would be awesome if you clarify that when do we should use External
layer ?
3- what are the Drivers ?
Thanks.
thanks to your awesome explanation about clean dart.
what am I doing in my projects is to create interfaces for local and remote datasources for ever feature, but after some investigations in codes, I figure out that there is only one IDataSource
interface for every feature(module), because I am pretty new to uncle bob's clean architecture, I want to ask you am I wrong ?
as an example, I will show you my user feature datasource:
abstract class UserLocalDataSource {
Future<void> initialize();
void save(UserDto dao);
UserDto get dao;
Stream<UserDto> get daoStream;
}
@Injectable(as: UserLocalDataSource)
class UserLocalDataSourceImpl extends HiveDb<UserDto, UserDtoAdapter>
implements UserLocalDataSource {
@override
UserDtoAdapter get adaptor => UserDtoAdapter();
@override
String get boxKey => 'user_box';
@override
UserDto get defaultValue => null;
}
and
abstract class UserRemoteDataSource {
Future<Either<ApiFailure, Response<Map<String, dynamic>>>> user({
UserInclude include,
});
Future<Either<ApiFailure, Response<Map<String, dynamic>>>> updateUser(
String encodedData,
);
Future<Either<ApiFailure, Response<Map<String, dynamic>>>> updateAvatar(
OnProgress onProgress,
File file,
);
}
@Injectable(as: UserRemoteDataSource)
class UserRemoteDataSourceImpl implements UserRemoteDataSource {
const UserRemoteDataSourceImpl(this.fileDataSource, this.flApi);
final RemoteFileDataSource fileDataSource;
final FlApi flApi;
@override
user({UserInclude include}) => flApi
.getMethod(
UserEndpoints.index().toPath,
option: FlApiOption(query: include.toMap),
)
.toDomain<Map<String, dynamic>>();
@override
updateUser(String encodedData) => flApi
.putMethod(UserEndpoints.update().toPath, body: encodedData)
.toDomain<Map<String, dynamic>>();
@override
updateAvatar(OnProgress onProgress, File file) =>
fileDataSource.upload<Map<String, dynamic>>(
url: UserEndpoints.image().toPath,
onProgress: onProgress,
flApi: flApi,
file: file,
);
}
I think if we decouple two datasources, it is easier to change the implementation of remote and local seperately.
thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.