SlideShare uma empresa Scribd logo
1 de 105
Baixar para ler offline
Better Faster
Stronger Dagger
Rafael Toledo
@_rafaeltoledo
Android Developer @ Concrete Solutions
www.rafaeltoledo.net
O que é Injeção de
Dependência?
@_rafaeltoledo
“Injeção de Dependência (ou Dependency
Injection, em inglês) é um padrão de
desenvolvimento de programas de
computadores utilizado quando é necessário
manter baixo o nível de acoplamento entre
diferentes módulos de um sistema. (...)”
@_rafaeltoledo
“Nesta solução as dependências entre os
módulos não são definidas
programaticamente, mas sim pela
configuração de uma infraestrutura de
software (container) que é responsável por
"injetar" em cada componente suas
dependências declaradas. A Injeção de
dependência se relaciona com o padrão
Inversão de controle mas não pode ser
considerada um sinônimo deste.”
Wikipedia, 2015
@_rafaeltoledo
?????????
@_rafaeltoledo
Diz respeito a separação de onde os
objetos são criados e onde são utilizados
@_rafaeltoledo
Em vez de criar, você pede
@_rafaeltoledo
class UserController {
void doLogic() {
try {
User user = RetrofitApi.getInstance().getUser(1);
new UserDaoImpl().save(user);
Logger.getForClass(UserController.class).log("Success");
} catch (IOException e) {
Logger.getForClass(UserController.class).logException(e);
}
}
}
@_rafaeltoledo
class UserController {
UserDaoImpl dao;
Logger logger;
UserApi api;
void doLogic() {
try {
api = RetrofitApi.getInstance();
User user = api.getUser(1);
dao = new UserDaoImpl();
dao.save(user);
logger = Logger.getForClass(UserController.class);
logger.log("Success");
} catch (IOException e) {
logger = Logger.getForClass(UserController.class);
logger.logException(e);
}
}
} @_rafaeltoledo
class UserController {
UserDao dao; // Interface!
Logger logger;
Api api;
void doLogic() {
try {
if (api == null) api = RetrofitApi.getInstance();
User user = api.getUser(1);
if (dao == null) dao = new UserDaoImpl();
dao.save(user);
if (logger == null) logger = Logger.getForClass(UserController.class);
logger.log("Success");
} catch (IOException e) {
if (logger == null) logger = Logger.getForClass(UserController.class);
logger.logException(e);
}
}
} @_rafaeltoledo
class UserController {
UserDao dao = new UserDaoImpl();
Logger logger = Logger.getForClass(UserController.class);
Api api = RetrofitApi.getInstance();
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) {
logger.logException(e);
}
}
}
@_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
UserDao
UserController
@_rafaeltoledo
UserDao
UserController
SessionManager
@_rafaeltoledo
UserDao
UserController
SessionManager
SignInController
@_rafaeltoledo
UserDao
UserController
SessionManager
SignInController
CookieJob
JobManager
JobController
PermissionChecker
ReminderJob
RoleController
CandyShopper
FruitJuicerJob
UnknownController
@_rafaeltoledo
UserDao
UserController
SessionManager
SignInController
CookieJob
JobManager
JobController
PermissionChecker
ReminderJob
RoleController
CandyShopper
FruitJuicerJob
UnknownController
EM
TODO
LUGAR!
@_rafaeltoledo
class UserDaoImpl implements UserDao {
public UserDaoImpl() {
//...
}
}
@_rafaeltoledo
class UserDaoImpl implements UserDao {
public UserDaoImpl(Context context) {
//...
}
}
@_rafaeltoledo
@_rafaeltoledo
Alteração em todas as classes!
@_rafaeltoledo
Alteração em todas as classes!
Muito retrabalho!
@_rafaeltoledo
Alteração em todas as classes!
Muito retrabalho!
@_rafaeltoledo
Alteração em todas as classes!
Muito retrabalho!
@_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController() {
dao = new UserDaoImpl();
api = RetrofitApi.getInstance();
logger = Logger.getForClass(UserController.class);
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
class UserController {
UserDao dao;
Logger logger;
Api api;
public UserController(UserDao dao, Api api, Logger logger) {
this.dao = dao;
this.api = api;
this.logger = logger;
}
void doLogic() {
try {
User user = api.getUser(1);
dao.save(user);
logger.log("Success");
} catch (IOException e) { logger.logException(e); }
}
} @_rafaeltoledo
DI: Separação do uso e criação de objetos
@_rafaeltoledo
DI: Separação do uso e criação de objetos
não há a necessidade de bibliotecas
ou frameworks!
@_rafaeltoledo
Desvantagem: muito boilerplate
@_rafaeltoledo
Spring, Guice, Dagger 1 & cia
#oldbutgold
@_rafaeltoledo
Spring, Guice, Dagger 1 & cia
#oldbutnot
@_rafaeltoledo
Dagger 2
@_rafaeltoledo
Dagger 2?
@_rafaeltoledo
Dagger 2
● Fork do Dagger, da Square, feito pela
Google
● Elimina todo o uso de reflections
● Construída sobre as anotações javax.
inject da especificação JSR-330
@_rafaeltoledo
Dagger 2
● Validação de todo o grafo de dependências
em tempo de compilação
● Menos flexível, se comparado ao Dagger 1 -
ex.: não possui module overriding
● Proguard configuration-free
@_rafaeltoledo
Dagger 2
● API enxuta!
● Código gerado é debugger-friendly
● Muito performático
● google.github.io/dagger
@_rafaeltoledo
public @interface Component {
Class<?>[] modules() default {};
Class<?>[] dependencies() default {};
}
public @interface Subcomponent {
Class<?>[] includes() default {};
}
public @interface Module {
Class<?>[] includes() default {};
}
public @interface Provides {
}
public @interface MapKey {
boolean unwrapValue() default true;
}
public interface Lazy<T> {
T get();
}
@_rafaeltoledo
// JSR-330
public @interface Inject {
}
public @interface Scope {
}
public @interface Qualifier {
}
@_rafaeltoledo
Como integro no meu projeto?
@_rafaeltoledo
// build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
allprojects {
repositories {
jcenter()
}
}
@_rafaeltoledo
// build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
}
}
allprojects {
repositories {
jcenter()
}
}
@_rafaeltoledo
// build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
@_rafaeltoledo
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId 'net.rafaeltoledo.tdc2015'
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName '1.0'
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
}
@_rafaeltoledo
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId 'net.rafaeltoledo.tdc2015'
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName '1.0'
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'
provided 'javax.annotation:javax.annotation-api:1.2'
}
@_rafaeltoledo
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId 'net.rafaeltoledo.tdc2015'
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName '1.0'
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'
provided 'javax.annotation:javax.annotation-api:1.2' // JSR-330
}
@_rafaeltoledo
E pronto!
@_rafaeltoledo
Vamos começar?
@_rafaeltoledo
@Inject
@Component @Module
@Provides
Dagger 2
@_rafaeltoledo
@Inject
● Parte da JSR-330
● Marca quais dependências devem ser
fornecidas pelo Dagger
● Pode aparecer de 3 formas no código
@_rafaeltoledo
public class TdcActivityPresenter {
private TdcActivity activity;
private TdcDataStore dataStore;
@Inject
public TdcActivityPresenter(TdcActivity activity,
TdcDataStore dataStore) {
this.activity = activity;
this.dataStore = dataStore;
}
}
1. No Construtor
@_rafaeltoledo
1. No Construtor
● Todas as dependências vem do grafo de
dependências do Dagger
● Anotar uma classe dessa forma faz com que
ela também faça parte do grafo de
dependências (podendo ser injetada em
outras classes)
@_rafaeltoledo
1. No Construtor
● Limitação: não podemos anotar mais que
um construtor com a anotação @Inject
@_rafaeltoledo
public class TdcActivity extends AppCompatActivity {
@Inject TdcActivityPresenter presenter;
@Inject SharedPreferences preferences;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
getComponent().inject(this);
}
}
2. Nos Atributos da Classe
@_rafaeltoledo
2. Nos Atributos da Classe
● A injeção nesse caso deve ser manual, caso
contrários os atributos serão todos nulos
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
getComponent().inject(this);
}
● Limitação: os atributos não podem ser
privados!
@_rafaeltoledo
public class TdcActivityPresenter {
private TdcActivity activity;
@Inject
public TdcActivityPresenter(TdcActivity activity) {
this.activity = activity;
}
@Inject
public void enableAnalytics(AnalyticsManager analytics) {
analytics.track(this);
}
}
3. Em métodos públicos
@_rafaeltoledo
3. Em métodos públicos
● Utilizado em conjunto com a anotação no
construtor da classe
● Para casos onde o objeto injetado
necessitamos da instância da própria classe
na dependência fornecida
@Inject
public void enableAnalytics(AnalyticsManager analytics) {
analytics.track(this);
}
@_rafaeltoledo
3. Em métodos públicos
● O método anotado é chamado
automaticamente logo após o construtor
@_rafaeltoledo
@Module
● Parte da API do Dagger
● Utilizada para identificar classes que
fornecem dependências
@_rafaeltoledo
@Module
public class DataModule {
@Provides @Singleton
public OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(10, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);
return okHttpClient;
}
@Provides @Singleton
public RestAdapter provideRestAdapter(OkHttpClient client) {
return new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setEndpoint("https://api.github.com")
.build();
}
} @_rafaeltoledo
@Module
public class DataModule {
@Provides @Singleton
public OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(10, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);
return okHttpClient;
}
@Provides @Singleton
public RestAdapter provideRestAdapter(OkHttpClient client) {
return new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setEndpoint("https://api.github.com")
.build();
}
} @_rafaeltoledo
@Provides
● Utilizada nas classes anotadas como
@Module para identificar quais métodos
retornam dependências
@_rafaeltoledo
@Module
public class DataModule {
@Provides @Singleton
public OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(10, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);
return okHttpClient;
}
@Provides @Singleton
public RestAdapter provideRestAdapter(OkHttpClient client) {
return new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setEndpoint("https://api.github.com")
.build();
}
} @_rafaeltoledo
@Module
public class DataModule {
@Provides @Singleton
public OkHttpClient provideOkHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(10, TimeUnit.SECONDS);
okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS);
return okHttpClient;
}
@Provides @Singleton
public RestAdapter provideRestAdapter(OkHttpClient client) {
return new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setEndpoint("https://api.github.com")
.build();
}
} @_rafaeltoledo
@Component
● É a anotação que liga os @Modules aos
@Injects
● É colocada em uma interface
● Define quais módulos possui, quem será
injetado
@_rafaeltoledo
@Component
● Precisa especificar obrigatoriamente seu
escopo (ciclo de vida de suas dependências)
● Pode publicar dependências
● Pode possuir outros componentes
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@Singleton // Escopo
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity); // Caso queira encadear
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager(); // Dependências visíveis
} // para outros componentes*
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@ActivityScope // Escopo personalizado
@Component(
modules = TdcActivityModule.class,
dependencies = TdcComponent.class
)
public interface TdcActivityComponent {
TdcActivity inject(TdcActivity activity);
TdcActivityPresenter presenter();
}
@_rafaeltoledo
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerMainComponent implements MainComponent {
private Provider<ApiService> provideApiServiceProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerMainComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static MainComponent create() {
return builder().build();
}
private void initialize(final Builder builder) {
this.provideApiServiceProvider =
ScopedProvider.create(MainModule_ProvideApiServiceFactory.create(builder.mainModule));
this.mainActivityMembersInjector = MainActivity_MembersInjector.create(
(MembersInjector) MembersInjectors.noOp(), provideApiServiceProvider);
}
@Override
public void inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
}
@_rafaeltoledo
public class TdcApp extends Application {
TdcAppComponent component;
@Override
public void onCreate() {
component = DaggerTdcAppComponent.create();
component = DaggerTdcAppComponent.builder()
.dataModule(new DataModule(this)) // Módulo com construtor
.build(); // parametrizado
}
}
Instanciando um Componente
@_rafaeltoledo
Dagger 2
Escopos dinâmicos
@_rafaeltoledo
Escopo = ciclo de vida do grafo de
dependências (componente)
@_rafaeltoledo
@Singleton
@Component(
modules = {
DataModule.class,
UiModule.class
}
)
public interface TdcAppComponent {
void inject(TdcApplication app);
MainActivity inject(MainActivity activity);
Application getApplication();
AnalyticsManager getAnalyticsManager();
}
@_rafaeltoledo
@ActivityScope // Escopo personalizado
@Component(
modules = TdcActivityModule.class,
dependencies = TdcComponent.class
)
public interface TdcActivityComponent {
TdcActivity inject(TdcActivity activity);
TdcActivityPresenter presenter();
}
@_rafaeltoledo
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface UserScope {
}
Definição de um escopo
@_rafaeltoledo
Exemplo de uso
Miroslaw Stanek frogermcs.github.io
@_rafaeltoledo
@Singleton
@Component(modules = DataModule.class)
public interface TdcAppComponent {
UserComponent plus(UserModule module);
// não é necessário expor as dependências
}
Implementação
@_rafaeltoledo
@UserScope
@Subcomponent(modules = UserModule.class)
public interface UserComponent {
UserActivityComponent plus(UserActivityModule module);
}
Implementação
@_rafaeltoledo
public class TdcApp extends Application {
TdcAppComponent component;
UserComponent userComponent;
public UserComponent createUserComponent(User user) {
userComponent = component.plus(new UserModule(user));
return userComponent;
}
public void releaseUserComponent() {
userComponent = null;
}
...
}
Implementação
@_rafaeltoledo
Dagger 2
Outras coisas legais!
@_rafaeltoledo
@Inject
Lazy<SharedPreferences> prefs;
void salvar() {
prefs.get().edit().putString("status", "ok!").apply();
}
Dependências “Preguiçosas”
@_rafaeltoledo
// No módulo
@Provides @Singleton
@ApiUrl String provideApiUrl(Context context) {
return context.getString(R.string.api_url);
}
@Provides @Singleton
@AccessToken String provideRestAdapter(SharedPreferences prefs) {
return prefs.getString("token", null);
}
// Na classe a ser injetada
@Inject @AccessToken
String accessToken;
Qualificadores
@_rafaeltoledo
// Declarando sua anotação
@MapKey(unwrapValue = true)
@interface GroupKey {
String value();
}
@MapKey
@_rafaeltoledo
// Fornecendo dependências no módulo
@Provides(type = Type.MAP)
@GroupKey("um")
String provideFirstValue() {
return "primeiro valor";
}
@Provides(type = Type.MAP)
@GroupKey("dois")
String provideSecondValue() {
return "segundo valor";
}
@MapKey
@_rafaeltoledo
// Uso
@Inject
Map<String, String> map; // {um=primeiro valor, dois=segundo valor}
Por enquanto, só aceita Map e Set, e valores
do tipo String e Enumeradores
@MapKey
@_rafaeltoledo
Ok! Tudo muito bonito mas...
@_rafaeltoledo
O que eu ganho de fato com tudo isso?
@_rafaeltoledo
Grandes benefícios
● Código mais limpo e organizado
● Melhorias no gerenciamento de objetos
(melhor controle de singletons)
● Código mais fácil de TESTAR
@_rafaeltoledo
Dagger 2 e Testes
● Programar orientado a interfaces - mocks
● Sobrescrita de Componentes e Módulos
@_rafaeltoledo
Dagger 2 e Testes
@Module
public class TestMainModule {
@Provides // Poderíamos fazer com o Retrofit Mock!
public ApiService provideApiService() {
return new ApiService() {
@Override
public List<Repo> listRepos() {
return Arrays.asList(
new Repo("my-test-repo"),
new Repo("another-test-repo")
);
}
};
}
} @_rafaeltoledo
Dagger 2 e Testes
@Component(modules = DebugMainModule.class)
public interface TestMainComponent extends MainComponent {
}
@_rafaeltoledo
Dagger 2 e Espresso 2
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
// ...
@Before
public void setUp() {
Instrumentation instrumentation =
InstrumentationRegistry.getInstrumentation();
MainApplication app = (MainApplication)
instrumentation.getTargetContext().getApplicationContext();
app.setComponent(DaggerDebugMainComponent.create());
rule.launchActivity(new Intent());
}
}
@_rafaeltoledo
Dagger 2 e Robolectric 3
@RunWith(RobolectricGradleTestRunner.class)
@Config(sdk = 21, constants = BuildConfig.class)
public class MainActivityTest {
// ...
@Before
public void setUp() {
MainComponent component = DaggerDebugMainComponent.create();
MainApplication app =
((MainApplication) RuntimeEnvironment.application)
.setComponent(component);
}
}
@_rafaeltoledo
Dagger 2
github.com/rafaeltoledo/dagger2-tdc2015
@_rafaeltoledo
Para saber mais
● Site oficial - google.github.io/dagger
● Dagger 2 - A New Type of Dependency
Injection (Gregory Kick) - vai.la/fdwt
● The Future of Dependency Injection with
Dagger 2 (Jake Wharton) - vai.la/fdwy
● froger_mcs Dev Blog - frogermcs.github.io
OBRIGADO!
rafaeltoledo.net
@_rafaeltoledo
Desenv. Android @ Concrete Solutions
concretesolutions.com.br/carreira

Mais conteúdo relacionado

Mais procurados

JUnit 5 vs JUnit 4
JUnit 5 vs JUnit 4JUnit 5 vs JUnit 4
JUnit 5 vs JUnit 4Ismael
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitDesenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitAdolfo Neto
 
Seminário sd android_exemplos
Seminário sd android_exemplosSeminário sd android_exemplos
Seminário sd android_exemplosCalvin Rodrigues
 
Como construir aplicações gráficas e applets
Como construir aplicações gráficas e appletsComo construir aplicações gráficas e applets
Como construir aplicações gráficas e appletsDenis L Presciliano
 
Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Giovanni Bassi
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIElias Nogueira
 
Introdução a testes unitários com jUnit
Introdução a testes unitários com jUnitIntrodução a testes unitários com jUnit
Introdução a testes unitários com jUnitLeonardo Soares
 
Testes de Unidade com JUnit
Testes de Unidade com JUnitTestes de Unidade com JUnit
Testes de Unidade com JUnitelliando dias
 
Palestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnitPalestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnitRobinson Castilho
 
JavaEE 7, na era do cloud computing
JavaEE 7, na era do cloud computingJavaEE 7, na era do cloud computing
JavaEE 7, na era do cloud computingEder Magalhães
 

Mais procurados (19)

JUnit 5 vs JUnit 4
JUnit 5 vs JUnit 4JUnit 5 vs JUnit 4
JUnit 5 vs JUnit 4
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
Liferay e Modularização com Arquitetura OSGi
Liferay e Modularização com Arquitetura OSGiLiferay e Modularização com Arquitetura OSGi
Liferay e Modularização com Arquitetura OSGi
 
Desenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com JunitDesenvolvimento Dirigido por Testes com Junit
Desenvolvimento Dirigido por Testes com Junit
 
Seminário sd android_exemplos
Seminário sd android_exemplosSeminário sd android_exemplos
Seminário sd android_exemplos
 
Como construir aplicações gráficas e applets
Como construir aplicações gráficas e appletsComo construir aplicações gráficas e applets
Como construir aplicações gráficas e applets
 
Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2Fazendo Injeção de dependência com Unity 1.2
Fazendo Injeção de dependência com Unity 1.2
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de API
 
JUnit
JUnitJUnit
JUnit
 
Introdução a testes unitários com jUnit
Introdução a testes unitários com jUnitIntrodução a testes unitários com jUnit
Introdução a testes unitários com jUnit
 
Testes de Unidade com JUnit
Testes de Unidade com JUnitTestes de Unidade com JUnit
Testes de Unidade com JUnit
 
Aula JPA
Aula JPAAula JPA
Aula JPA
 
Vraptor
VraptorVraptor
Vraptor
 
Robotium_Sikuli
Robotium_SikuliRobotium_Sikuli
Robotium_Sikuli
 
Introdução ao JavaFX
Introdução ao JavaFXIntrodução ao JavaFX
Introdução ao JavaFX
 
Maven
MavenMaven
Maven
 
Conhecendo o Spring
Conhecendo o SpringConhecendo o Spring
Conhecendo o Spring
 
Palestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnitPalestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnit
 
JavaEE 7, na era do cloud computing
JavaEE 7, na era do cloud computingJavaEE 7, na era do cloud computing
JavaEE 7, na era do cloud computing
 

Destaque

Design a arte de materializar as decisoes de negocios
Design a arte de materializar as decisoes de negociosDesign a arte de materializar as decisoes de negocios
Design a arte de materializar as decisoes de negociostdc-globalcode
 
sap startup focus acelerando startus brasileiras com sap hana
sap startup focus acelerando startus brasileiras com sap hanasap startup focus acelerando startus brasileiras com sap hana
sap startup focus acelerando startus brasileiras com sap hanatdc-globalcode
 
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...tdc-globalcode
 
O que aprendi com minha empresa
O que aprendi com minha empresaO que aprendi com minha empresa
O que aprendi com minha empresatdc-globalcode
 
De 0 a10000 usuarios em 3 meses
De 0 a10000 usuarios em 3 mesesDe 0 a10000 usuarios em 3 meses
De 0 a10000 usuarios em 3 mesestdc-globalcode
 
o que e ser cio de uma startup?
o que e ser cio de uma startup?o que e ser cio de uma startup?
o que e ser cio de uma startup?tdc-globalcode
 
como esta a arquitetura do seu app?
como esta a arquitetura do seu app?como esta a arquitetura do seu app?
como esta a arquitetura do seu app?tdc-globalcode
 
Criando app Android utilizando Kotlin
Criando app Android utilizando KotlinCriando app Android utilizando Kotlin
Criando app Android utilizando KotlinLuiz Henrique Santana
 
Reconstruindo a Torre de Babel com RequireJS
Reconstruindo a Torre de Babel com RequireJSReconstruindo a Torre de Babel com RequireJS
Reconstruindo a Torre de Babel com RequireJStdc-globalcode
 
Repaint/Reflow/Dom/RenderTree - Renderizando uma página web
Repaint/Reflow/Dom/RenderTree - Renderizando uma página webRepaint/Reflow/Dom/RenderTree - Renderizando uma página web
Repaint/Reflow/Dom/RenderTree - Renderizando uma página webtdc-globalcode
 
introdução a pretotyping fazer a coisa certa mais do que fazer certo a coisa
introdução a pretotyping  fazer a coisa certa mais do que fazer certo a coisaintrodução a pretotyping  fazer a coisa certa mais do que fazer certo a coisa
introdução a pretotyping fazer a coisa certa mais do que fazer certo a coisatdc-globalcode
 
Instagram: que tipo de conteúdo o público prefere?
Instagram: que tipo de conteúdo o público prefere?Instagram: que tipo de conteúdo o público prefere?
Instagram: que tipo de conteúdo o público prefere?tdc-globalcode
 
cakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentecakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentetdc-globalcode
 
Como impulsionar a sua carreira atraves das redes sociais?
Como impulsionar a sua carreira atraves das redes sociais?Como impulsionar a sua carreira atraves das redes sociais?
Como impulsionar a sua carreira atraves das redes sociais?tdc-globalcode
 
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos RailsPolo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Railstdc-globalcode
 
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...tdc-globalcode
 
Gere resultados com Facebook Ads
Gere resultados com Facebook AdsGere resultados com Facebook Ads
Gere resultados com Facebook Adstdc-globalcode
 
Gerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalk
Gerenciando o ciclo de vida de aplicações com AWS Elastic BeanstalkGerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalk
Gerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalktdc-globalcode
 

Destaque (20)

Design a arte de materializar as decisoes de negocios
Design a arte de materializar as decisoes de negociosDesign a arte de materializar as decisoes de negocios
Design a arte de materializar as decisoes de negocios
 
sap startup focus acelerando startus brasileiras com sap hana
sap startup focus acelerando startus brasileiras com sap hanasap startup focus acelerando startus brasileiras com sap hana
sap startup focus acelerando startus brasileiras com sap hana
 
Por que sua próxima aplicação web deve ser em Clojure?
Por que sua próxima aplicação web deve ser em Clojure?Por que sua próxima aplicação web deve ser em Clojure?
Por que sua próxima aplicação web deve ser em Clojure?
 
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...
Fundamentos de Akka.net para sistemas concorrentes e distribuidos usando o mo...
 
O que aprendi com minha empresa
O que aprendi com minha empresaO que aprendi com minha empresa
O que aprendi com minha empresa
 
De 0 a10000 usuarios em 3 meses
De 0 a10000 usuarios em 3 mesesDe 0 a10000 usuarios em 3 meses
De 0 a10000 usuarios em 3 meses
 
o que e ser cio de uma startup?
o que e ser cio de uma startup?o que e ser cio de uma startup?
o que e ser cio de uma startup?
 
como esta a arquitetura do seu app?
como esta a arquitetura do seu app?como esta a arquitetura do seu app?
como esta a arquitetura do seu app?
 
Criando app Android utilizando Kotlin
Criando app Android utilizando KotlinCriando app Android utilizando Kotlin
Criando app Android utilizando Kotlin
 
Reconstruindo a Torre de Babel com RequireJS
Reconstruindo a Torre de Babel com RequireJSReconstruindo a Torre de Babel com RequireJS
Reconstruindo a Torre de Babel com RequireJS
 
Repaint/Reflow/Dom/RenderTree - Renderizando uma página web
Repaint/Reflow/Dom/RenderTree - Renderizando uma página webRepaint/Reflow/Dom/RenderTree - Renderizando uma página web
Repaint/Reflow/Dom/RenderTree - Renderizando uma página web
 
Do relogio ao carro
Do relogio ao carroDo relogio ao carro
Do relogio ao carro
 
introdução a pretotyping fazer a coisa certa mais do que fazer certo a coisa
introdução a pretotyping  fazer a coisa certa mais do que fazer certo a coisaintrodução a pretotyping  fazer a coisa certa mais do que fazer certo a coisa
introdução a pretotyping fazer a coisa certa mais do que fazer certo a coisa
 
Instagram: que tipo de conteúdo o público prefere?
Instagram: que tipo de conteúdo o público prefere?Instagram: que tipo de conteúdo o público prefere?
Instagram: que tipo de conteúdo o público prefere?
 
cakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gentecakephp 3.0 o bolo ainda serve muita gente
cakephp 3.0 o bolo ainda serve muita gente
 
Como impulsionar a sua carreira atraves das redes sociais?
Como impulsionar a sua carreira atraves das redes sociais?Como impulsionar a sua carreira atraves das redes sociais?
Como impulsionar a sua carreira atraves das redes sociais?
 
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos RailsPolo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
Polo: Desenvolvendo os problemas de inconsistência de dados em projetos Rails
 
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...
A experiência da AGCO ao adotar o BDD em seus projetos: uma experiência excit...
 
Gere resultados com Facebook Ads
Gere resultados com Facebook AdsGere resultados com Facebook Ads
Gere resultados com Facebook Ads
 
Gerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalk
Gerenciando o ciclo de vida de aplicações com AWS Elastic BeanstalkGerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalk
Gerenciando o ciclo de vida de aplicações com AWS Elastic Beanstalk
 

Semelhante a DI: Separação do uso e criação de objetos com Dagger 2

(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - SubalgoritmosCarlos Santos
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?Rafael Benevides
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javJulio Viegas
 
Dependency injection WTF? - PHPSC Conference 2012
Dependency injection WTF? - PHPSC Conference 2012Dependency injection WTF? - PHPSC Conference 2012
Dependency injection WTF? - PHPSC Conference 2012Luís Cobucci
 
T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)Carlos Santos
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Elton Minetto
 
LabMM3 - Aula teórica 08
LabMM3 - Aula teórica 08LabMM3 - Aula teórica 08
LabMM3 - Aula teórica 08Carlos Santos
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Strutseduan
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Androidtdc-globalcode
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Rafael Benevides
 
Como escolher o Framework Java para web?
Como escolher o Framework Java para web?Como escolher o Framework Java para web?
Como escolher o Framework Java para web?Anderson Araújo
 
Paradigmas de Linguagens de Programação - Modularização, componentização e re...
Paradigmas de Linguagens de Programação - Modularização, componentização e re...Paradigmas de Linguagens de Programação - Modularização, componentização e re...
Paradigmas de Linguagens de Programação - Modularização, componentização e re...Adriano Teixeira de Souza
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeRafael Benevides
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5Diego Pacheco
 

Semelhante a DI: Separação do uso e criação de objetos com Dagger 2 (20)

(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos(A10) LabMM3 - JavaScript - Subalgoritmos
(A10) LabMM3 - JavaScript - Subalgoritmos
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_jav
 
Dependency injection WTF? - PHPSC Conference 2012
Dependency injection WTF? - PHPSC Conference 2012Dependency injection WTF? - PHPSC Conference 2012
Dependency injection WTF? - PHPSC Conference 2012
 
T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)T10_LM3: Subalgoritmos/funções (2013-2014)
T10_LM3: Subalgoritmos/funções (2013-2014)
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
Introdução ao Zend Framework 2
Introdução ao Zend Framework 2Introdução ao Zend Framework 2
Introdução ao Zend Framework 2
 
LabMM3 - Aula teórica 08
LabMM3 - Aula teórica 08LabMM3 - Aula teórica 08
LabMM3 - Aula teórica 08
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Struts
 
VRaptor4
VRaptor4VRaptor4
VRaptor4
 
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no AndroidTDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
 
Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007Apostilava Java EE 5 - 2007
Apostilava Java EE 5 - 2007
 
Como escolher o Framework Java para web?
Como escolher o Framework Java para web?Como escolher o Framework Java para web?
Como escolher o Framework Java para web?
 
Paradigmas de Linguagens de Programação - Modularização, componentização e re...
Paradigmas de Linguagens de Programação - Modularização, componentização e re...Paradigmas de Linguagens de Programação - Modularização, componentização e re...
Paradigmas de Linguagens de Programação - Modularização, componentização e re...
 
JADE+JENA
JADE+JENAJADE+JENA
JADE+JENA
 
CDI Extensions e DeltaSpike
CDI Extensions e DeltaSpikeCDI Extensions e DeltaSpike
CDI Extensions e DeltaSpike
 
Precisamos falar sobre Gradle
Precisamos falar sobre GradlePrecisamos falar sobre Gradle
Precisamos falar sobre Gradle
 
Java1
Java1Java1
Java1
 
Spring framework 2.5
Spring framework 2.5Spring framework 2.5
Spring framework 2.5
 

Mais de tdc-globalcode

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadetdc-globalcode
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...tdc-globalcode
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucessotdc-globalcode
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPAtdc-globalcode
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinotdc-globalcode
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...tdc-globalcode
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicestdc-globalcode
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publicatdc-globalcode
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#tdc-globalcode
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocustdc-globalcode
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?tdc-globalcode
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golangtdc-globalcode
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QAtdc-globalcode
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciatdc-globalcode
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Servicetdc-globalcode
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETtdc-globalcode
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8tdc-globalcode
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...tdc-globalcode
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#tdc-globalcode
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Coretdc-globalcode
 

Mais de tdc-globalcode (20)

TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidadeTDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
TDC2019 Intel Software Day - Visao Computacional e IA a servico da humanidade
 
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
TDC2019 Intel Software Day - Tecnicas de Programacao Paralela em Machine Lear...
 
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de SucessoTDC2019 Intel Software Day - ACATE - Cases de Sucesso
TDC2019 Intel Software Day - ACATE - Cases de Sucesso
 
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPATDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
TDC2019 Intel Software Day - Otimizacao grafica com o Intel GPA
 
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVinoTDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
TDC2019 Intel Software Day - Deteccao de objetos em tempo real com OpenVino
 
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
TDC2019 Intel Software Day - OpenCV: Inteligencia artificial e Visao Computac...
 
TDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devicesTDC2019 Intel Software Day - Inferencia de IA em edge devices
TDC2019 Intel Software Day - Inferencia de IA em edge devices
 
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca PublicaTrilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
Trilha BigData - Banco de Dados Orientado a Grafos na Seguranca Publica
 
Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#Trilha .Net - Programacao funcional usando f#
Trilha .Net - Programacao funcional usando f#
 
TDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case EasylocusTDC2018SP | Trilha Go - Case Easylocus
TDC2018SP | Trilha Go - Case Easylocus
 
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
TDC2018SP | Trilha Modern Web - Para onde caminha a Web?
 
TDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em GolangTDC2018SP | Trilha Go - Clean architecture em Golang
TDC2018SP | Trilha Go - Clean architecture em Golang
 
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QATDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
TDC2018SP | Trilha Go - "Go" tambem e linguagem de QA
 
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendenciaTDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
TDC2018SP | Trilha Mobile - Digital Wallets - Seguranca, inovacao e tendencia
 
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR ServiceTDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
TDC2018SP | Trilha .Net - Real Time apps com Azure SignalR Service
 
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NETTDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
TDC2018SP | Trilha .Net - Passado, Presente e Futuro do .NET
 
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
TDC2018SP | Trilha .Net - Novidades do C# 7 e 8
 
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
TDC2018SP | Trilha .Net - Obtendo metricas com TDD utilizando build automatiz...
 
TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#TDC2018SP | Trilha .Net - .NET funcional com F#
TDC2018SP | Trilha .Net - .NET funcional com F#
 
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net CoreTDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor  em .Net Core
TDC2018SP | Trilha .Net - Crie SPAs com Razor e C# usando Blazor em .Net Core
 

Último

Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptx
Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptxSlide de exemplo sobre o Sítio do Pica Pau Amarelo.pptx
Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptxconcelhovdragons
 
Mesoamérica.Astecas,inca,maias , olmecas
Mesoamérica.Astecas,inca,maias , olmecasMesoamérica.Astecas,inca,maias , olmecas
Mesoamérica.Astecas,inca,maias , olmecasRicardo Diniz campos
 
geografia 7 ano - relevo, altitude, topos do mundo
geografia 7 ano - relevo, altitude, topos do mundogeografia 7 ano - relevo, altitude, topos do mundo
geografia 7 ano - relevo, altitude, topos do mundonialb
 
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdf
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdfcartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdf
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdfIedaGoethe
 
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptx
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptxQUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptx
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptxIsabellaGomes58
 
Guia completo da Previdênci a - Reforma .pdf
Guia completo da Previdênci a - Reforma .pdfGuia completo da Previdênci a - Reforma .pdf
Guia completo da Previdênci a - Reforma .pdfEyshilaKelly1
 
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptx
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptxSlides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptx
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptxLuizHenriquedeAlmeid6
 
Programa de Intervenção com Habilidades Motoras
Programa de Intervenção com Habilidades MotorasPrograma de Intervenção com Habilidades Motoras
Programa de Intervenção com Habilidades MotorasCassio Meira Jr.
 
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024HORA DO CONTO4_BECRE D. CARLOS I_2023_2024
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024Sandra Pratas
 
O guia definitivo para conquistar a aprovação em concurso público.pdf
O guia definitivo para conquistar a aprovação em concurso público.pdfO guia definitivo para conquistar a aprovação em concurso público.pdf
O guia definitivo para conquistar a aprovação em concurso público.pdfErasmo Portavoz
 
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptx
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptxSlides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptx
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptxLuizHenriquedeAlmeid6
 
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNAS
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNASQUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNAS
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNASEdinardo Aguiar
 
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptx
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptxÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptx
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptxDeyvidBriel
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Centro Jacques Delors
 
637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano
637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano
637743470-Mapa-Mental-Portugue-s-1.pdf 4 anoAdelmaTorres2
 
ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024Jeanoliveira597523
 
Doutrina Deus filho e Espírito Santo.pptx
Doutrina Deus filho e Espírito Santo.pptxDoutrina Deus filho e Espírito Santo.pptx
Doutrina Deus filho e Espírito Santo.pptxThye Oliver
 
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...LizanSantos1
 
Aula 13 8º Ano Cap.04 Revolução Francesa.pptx
Aula 13 8º Ano Cap.04 Revolução Francesa.pptxAula 13 8º Ano Cap.04 Revolução Francesa.pptx
Aula 13 8º Ano Cap.04 Revolução Francesa.pptxBiancaNogueira42
 
Sociologia Contemporânea - Uma Abordagem dos principais autores
Sociologia Contemporânea - Uma Abordagem dos principais autoresSociologia Contemporânea - Uma Abordagem dos principais autores
Sociologia Contemporânea - Uma Abordagem dos principais autoresaulasgege
 

Último (20)

Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptx
Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptxSlide de exemplo sobre o Sítio do Pica Pau Amarelo.pptx
Slide de exemplo sobre o Sítio do Pica Pau Amarelo.pptx
 
Mesoamérica.Astecas,inca,maias , olmecas
Mesoamérica.Astecas,inca,maias , olmecasMesoamérica.Astecas,inca,maias , olmecas
Mesoamérica.Astecas,inca,maias , olmecas
 
geografia 7 ano - relevo, altitude, topos do mundo
geografia 7 ano - relevo, altitude, topos do mundogeografia 7 ano - relevo, altitude, topos do mundo
geografia 7 ano - relevo, altitude, topos do mundo
 
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdf
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdfcartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdf
cartilha-pdi-plano-de-desenvolvimento-individual-do-estudante.pdf
 
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptx
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptxQUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptx
QUARTA - 1EM SOCIOLOGIA - Aprender a pesquisar.pptx
 
Guia completo da Previdênci a - Reforma .pdf
Guia completo da Previdênci a - Reforma .pdfGuia completo da Previdênci a - Reforma .pdf
Guia completo da Previdênci a - Reforma .pdf
 
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptx
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptxSlides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptx
Slides Lição 4, CPAD, Como se Conduzir na Caminhada, 2Tr24.pptx
 
Programa de Intervenção com Habilidades Motoras
Programa de Intervenção com Habilidades MotorasPrograma de Intervenção com Habilidades Motoras
Programa de Intervenção com Habilidades Motoras
 
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024HORA DO CONTO4_BECRE D. CARLOS I_2023_2024
HORA DO CONTO4_BECRE D. CARLOS I_2023_2024
 
O guia definitivo para conquistar a aprovação em concurso público.pdf
O guia definitivo para conquistar a aprovação em concurso público.pdfO guia definitivo para conquistar a aprovação em concurso público.pdf
O guia definitivo para conquistar a aprovação em concurso público.pdf
 
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptx
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptxSlides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptx
Slides Lição 2, Central Gospel, A Volta Do Senhor Jesus , 1Tr24.pptx
 
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNAS
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNASQUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNAS
QUIZ DE MATEMATICA SHOW DO MILHÃO PREPARAÇÃO ÇPARA AVALIAÇÕES EXTERNAS
 
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptx
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptxÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptx
ÁREA DE FIGURAS PLANAS - DESCRITOR DE MATEMATICA D12 ENSINO MEDIO.pptx
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029
 
637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano
637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano
637743470-Mapa-Mental-Portugue-s-1.pdf 4 ano
 
ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024
 
Doutrina Deus filho e Espírito Santo.pptx
Doutrina Deus filho e Espírito Santo.pptxDoutrina Deus filho e Espírito Santo.pptx
Doutrina Deus filho e Espírito Santo.pptx
 
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...
Intolerância religiosa. Trata-se de uma apresentação sobre o respeito a diver...
 
Aula 13 8º Ano Cap.04 Revolução Francesa.pptx
Aula 13 8º Ano Cap.04 Revolução Francesa.pptxAula 13 8º Ano Cap.04 Revolução Francesa.pptx
Aula 13 8º Ano Cap.04 Revolução Francesa.pptx
 
Sociologia Contemporânea - Uma Abordagem dos principais autores
Sociologia Contemporânea - Uma Abordagem dos principais autoresSociologia Contemporânea - Uma Abordagem dos principais autores
Sociologia Contemporânea - Uma Abordagem dos principais autores
 

DI: Separação do uso e criação de objetos com Dagger 2

  • 2. Rafael Toledo @_rafaeltoledo Android Developer @ Concrete Solutions www.rafaeltoledo.net
  • 3. O que é Injeção de Dependência? @_rafaeltoledo
  • 4. “Injeção de Dependência (ou Dependency Injection, em inglês) é um padrão de desenvolvimento de programas de computadores utilizado quando é necessário manter baixo o nível de acoplamento entre diferentes módulos de um sistema. (...)” @_rafaeltoledo
  • 5. “Nesta solução as dependências entre os módulos não são definidas programaticamente, mas sim pela configuração de uma infraestrutura de software (container) que é responsável por "injetar" em cada componente suas dependências declaradas. A Injeção de dependência se relaciona com o padrão Inversão de controle mas não pode ser considerada um sinônimo deste.” Wikipedia, 2015 @_rafaeltoledo
  • 7. Diz respeito a separação de onde os objetos são criados e onde são utilizados @_rafaeltoledo
  • 8. Em vez de criar, você pede @_rafaeltoledo
  • 9. class UserController { void doLogic() { try { User user = RetrofitApi.getInstance().getUser(1); new UserDaoImpl().save(user); Logger.getForClass(UserController.class).log("Success"); } catch (IOException e) { Logger.getForClass(UserController.class).logException(e); } } } @_rafaeltoledo
  • 10. class UserController { UserDaoImpl dao; Logger logger; UserApi api; void doLogic() { try { api = RetrofitApi.getInstance(); User user = api.getUser(1); dao = new UserDaoImpl(); dao.save(user); logger = Logger.getForClass(UserController.class); logger.log("Success"); } catch (IOException e) { logger = Logger.getForClass(UserController.class); logger.logException(e); } } } @_rafaeltoledo
  • 11. class UserController { UserDao dao; // Interface! Logger logger; Api api; void doLogic() { try { if (api == null) api = RetrofitApi.getInstance(); User user = api.getUser(1); if (dao == null) dao = new UserDaoImpl(); dao.save(user); if (logger == null) logger = Logger.getForClass(UserController.class); logger.log("Success"); } catch (IOException e) { if (logger == null) logger = Logger.getForClass(UserController.class); logger.logException(e); } } } @_rafaeltoledo
  • 12. class UserController { UserDao dao = new UserDaoImpl(); Logger logger = Logger.getForClass(UserController.class); Api api = RetrofitApi.getInstance(); void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 13. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 14. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 15. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 16. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 22. class UserDaoImpl implements UserDao { public UserDaoImpl() { //... } } @_rafaeltoledo
  • 23. class UserDaoImpl implements UserDao { public UserDaoImpl(Context context) { //... } } @_rafaeltoledo
  • 25. Alteração em todas as classes! @_rafaeltoledo
  • 26. Alteração em todas as classes! Muito retrabalho! @_rafaeltoledo
  • 27. Alteração em todas as classes! Muito retrabalho! @_rafaeltoledo
  • 28. Alteração em todas as classes! Muito retrabalho! @_rafaeltoledo
  • 29. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 30. class UserController { UserDao dao; Logger logger; Api api; public UserController() { dao = new UserDaoImpl(); api = RetrofitApi.getInstance(); logger = Logger.getForClass(UserController.class); } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 31. class UserController { UserDao dao; Logger logger; Api api; public UserController(UserDao dao, Api api, Logger logger) { this.dao = dao; this.api = api; this.logger = logger; } void doLogic() { try { User user = api.getUser(1); dao.save(user); logger.log("Success"); } catch (IOException e) { logger.logException(e); } } } @_rafaeltoledo
  • 32. DI: Separação do uso e criação de objetos @_rafaeltoledo
  • 33. DI: Separação do uso e criação de objetos não há a necessidade de bibliotecas ou frameworks! @_rafaeltoledo
  • 35. Spring, Guice, Dagger 1 & cia #oldbutgold @_rafaeltoledo
  • 36. Spring, Guice, Dagger 1 & cia #oldbutnot @_rafaeltoledo
  • 39. Dagger 2 ● Fork do Dagger, da Square, feito pela Google ● Elimina todo o uso de reflections ● Construída sobre as anotações javax. inject da especificação JSR-330 @_rafaeltoledo
  • 40. Dagger 2 ● Validação de todo o grafo de dependências em tempo de compilação ● Menos flexível, se comparado ao Dagger 1 - ex.: não possui module overriding ● Proguard configuration-free @_rafaeltoledo
  • 41. Dagger 2 ● API enxuta! ● Código gerado é debugger-friendly ● Muito performático ● google.github.io/dagger @_rafaeltoledo
  • 42. public @interface Component { Class<?>[] modules() default {}; Class<?>[] dependencies() default {}; } public @interface Subcomponent { Class<?>[] includes() default {}; } public @interface Module { Class<?>[] includes() default {}; } public @interface Provides { } public @interface MapKey { boolean unwrapValue() default true; } public interface Lazy<T> { T get(); } @_rafaeltoledo
  • 43. // JSR-330 public @interface Inject { } public @interface Scope { } public @interface Qualifier { } @_rafaeltoledo
  • 44. Como integro no meu projeto? @_rafaeltoledo
  • 45. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.1' } } allprojects { repositories { jcenter() } } @_rafaeltoledo
  • 46. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.1' } } allprojects { repositories { jcenter() } } @_rafaeltoledo
  • 47. // build.gradle buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.1' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } allprojects { repositories { jcenter() } } @_rafaeltoledo
  • 48. apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:23.0.1' } @_rafaeltoledo
  • 49. apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.google.dagger:dagger:2.0.1' apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'javax.annotation:javax.annotation-api:1.2' } @_rafaeltoledo
  • 50. apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 23 buildToolsVersion '23.0.1' defaultConfig { applicationId 'net.rafaeltoledo.tdc2015' minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName '1.0' } } dependencies { compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.google.dagger:dagger:2.0.1' apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'javax.annotation:javax.annotation-api:1.2' // JSR-330 } @_rafaeltoledo
  • 54. @Inject ● Parte da JSR-330 ● Marca quais dependências devem ser fornecidas pelo Dagger ● Pode aparecer de 3 formas no código @_rafaeltoledo
  • 55. public class TdcActivityPresenter { private TdcActivity activity; private TdcDataStore dataStore; @Inject public TdcActivityPresenter(TdcActivity activity, TdcDataStore dataStore) { this.activity = activity; this.dataStore = dataStore; } } 1. No Construtor @_rafaeltoledo
  • 56. 1. No Construtor ● Todas as dependências vem do grafo de dependências do Dagger ● Anotar uma classe dessa forma faz com que ela também faça parte do grafo de dependências (podendo ser injetada em outras classes) @_rafaeltoledo
  • 57. 1. No Construtor ● Limitação: não podemos anotar mais que um construtor com a anotação @Inject @_rafaeltoledo
  • 58. public class TdcActivity extends AppCompatActivity { @Inject TdcActivityPresenter presenter; @Inject SharedPreferences preferences; @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); getComponent().inject(this); } } 2. Nos Atributos da Classe @_rafaeltoledo
  • 59. 2. Nos Atributos da Classe ● A injeção nesse caso deve ser manual, caso contrários os atributos serão todos nulos @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); getComponent().inject(this); } ● Limitação: os atributos não podem ser privados! @_rafaeltoledo
  • 60. public class TdcActivityPresenter { private TdcActivity activity; @Inject public TdcActivityPresenter(TdcActivity activity) { this.activity = activity; } @Inject public void enableAnalytics(AnalyticsManager analytics) { analytics.track(this); } } 3. Em métodos públicos @_rafaeltoledo
  • 61. 3. Em métodos públicos ● Utilizado em conjunto com a anotação no construtor da classe ● Para casos onde o objeto injetado necessitamos da instância da própria classe na dependência fornecida @Inject public void enableAnalytics(AnalyticsManager analytics) { analytics.track(this); } @_rafaeltoledo
  • 62. 3. Em métodos públicos ● O método anotado é chamado automaticamente logo após o construtor @_rafaeltoledo
  • 63. @Module ● Parte da API do Dagger ● Utilizada para identificar classes que fornecem dependências @_rafaeltoledo
  • 64. @Module public class DataModule { @Provides @Singleton public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS); okHttpClient.setReadTimeout(10, TimeUnit.SECONDS); okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); return okHttpClient; } @Provides @Singleton public RestAdapter provideRestAdapter(OkHttpClient client) { return new RestAdapter.Builder() .setClient(new OkClient(okHttpClient)) .setEndpoint("https://api.github.com") .build(); } } @_rafaeltoledo
  • 65. @Module public class DataModule { @Provides @Singleton public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS); okHttpClient.setReadTimeout(10, TimeUnit.SECONDS); okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); return okHttpClient; } @Provides @Singleton public RestAdapter provideRestAdapter(OkHttpClient client) { return new RestAdapter.Builder() .setClient(new OkClient(okHttpClient)) .setEndpoint("https://api.github.com") .build(); } } @_rafaeltoledo
  • 66. @Provides ● Utilizada nas classes anotadas como @Module para identificar quais métodos retornam dependências @_rafaeltoledo
  • 67. @Module public class DataModule { @Provides @Singleton public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS); okHttpClient.setReadTimeout(10, TimeUnit.SECONDS); okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); return okHttpClient; } @Provides @Singleton public RestAdapter provideRestAdapter(OkHttpClient client) { return new RestAdapter.Builder() .setClient(new OkClient(okHttpClient)) .setEndpoint("https://api.github.com") .build(); } } @_rafaeltoledo
  • 68. @Module public class DataModule { @Provides @Singleton public OkHttpClient provideOkHttpClient() { OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setConnectionTimeout(10, TimeUnit.SECONDS); okHttpClient.setReadTimeout(10, TimeUnit.SECONDS); okHttpClient.setWriteTimeout(10, TimeUnit.SECONDS); return okHttpClient; } @Provides @Singleton public RestAdapter provideRestAdapter(OkHttpClient client) { return new RestAdapter.Builder() .setClient(new OkClient(okHttpClient)) .setEndpoint("https://api.github.com") .build(); } } @_rafaeltoledo
  • 69. @Component ● É a anotação que liga os @Modules aos @Injects ● É colocada em uma interface ● Define quais módulos possui, quem será injetado @_rafaeltoledo
  • 70. @Component ● Precisa especificar obrigatoriamente seu escopo (ciclo de vida de suas dependências) ● Pode publicar dependências ● Pode possuir outros componentes @_rafaeltoledo
  • 71. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 72. @Singleton // Escopo @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 73. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 74. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); // Caso queira encadear Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 75. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); // Dependências visíveis } // para outros componentes* @_rafaeltoledo
  • 76. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 77. @ActivityScope // Escopo personalizado @Component( modules = TdcActivityModule.class, dependencies = TdcComponent.class ) public interface TdcActivityComponent { TdcActivity inject(TdcActivity activity); TdcActivityPresenter presenter(); } @_rafaeltoledo
  • 78. @Generated("dagger.internal.codegen.ComponentProcessor") public final class DaggerMainComponent implements MainComponent { private Provider<ApiService> provideApiServiceProvider; private MembersInjector<MainActivity> mainActivityMembersInjector; private DaggerMainComponent(Builder builder) { assert builder != null; initialize(builder); } public static Builder builder() { return new Builder(); } public static MainComponent create() { return builder().build(); } private void initialize(final Builder builder) { this.provideApiServiceProvider = ScopedProvider.create(MainModule_ProvideApiServiceFactory.create(builder.mainModule)); this.mainActivityMembersInjector = MainActivity_MembersInjector.create( (MembersInjector) MembersInjectors.noOp(), provideApiServiceProvider); } @Override public void inject(MainActivity activity) { mainActivityMembersInjector.injectMembers(activity); } } @_rafaeltoledo
  • 79. public class TdcApp extends Application { TdcAppComponent component; @Override public void onCreate() { component = DaggerTdcAppComponent.create(); component = DaggerTdcAppComponent.builder() .dataModule(new DataModule(this)) // Módulo com construtor .build(); // parametrizado } } Instanciando um Componente @_rafaeltoledo
  • 81. Escopo = ciclo de vida do grafo de dependências (componente) @_rafaeltoledo
  • 82. @Singleton @Component( modules = { DataModule.class, UiModule.class } ) public interface TdcAppComponent { void inject(TdcApplication app); MainActivity inject(MainActivity activity); Application getApplication(); AnalyticsManager getAnalyticsManager(); } @_rafaeltoledo
  • 83. @ActivityScope // Escopo personalizado @Component( modules = TdcActivityModule.class, dependencies = TdcComponent.class ) public interface TdcActivityComponent { TdcActivity inject(TdcActivity activity); TdcActivityPresenter presenter(); } @_rafaeltoledo
  • 84. @Scope @Retention(RetentionPolicy.RUNTIME) public @interface UserScope { } Definição de um escopo @_rafaeltoledo
  • 85. Exemplo de uso Miroslaw Stanek frogermcs.github.io @_rafaeltoledo
  • 86. @Singleton @Component(modules = DataModule.class) public interface TdcAppComponent { UserComponent plus(UserModule module); // não é necessário expor as dependências } Implementação @_rafaeltoledo
  • 87. @UserScope @Subcomponent(modules = UserModule.class) public interface UserComponent { UserActivityComponent plus(UserActivityModule module); } Implementação @_rafaeltoledo
  • 88. public class TdcApp extends Application { TdcAppComponent component; UserComponent userComponent; public UserComponent createUserComponent(User user) { userComponent = component.plus(new UserModule(user)); return userComponent; } public void releaseUserComponent() { userComponent = null; } ... } Implementação @_rafaeltoledo
  • 89. Dagger 2 Outras coisas legais! @_rafaeltoledo
  • 90. @Inject Lazy<SharedPreferences> prefs; void salvar() { prefs.get().edit().putString("status", "ok!").apply(); } Dependências “Preguiçosas” @_rafaeltoledo
  • 91. // No módulo @Provides @Singleton @ApiUrl String provideApiUrl(Context context) { return context.getString(R.string.api_url); } @Provides @Singleton @AccessToken String provideRestAdapter(SharedPreferences prefs) { return prefs.getString("token", null); } // Na classe a ser injetada @Inject @AccessToken String accessToken; Qualificadores @_rafaeltoledo
  • 92. // Declarando sua anotação @MapKey(unwrapValue = true) @interface GroupKey { String value(); } @MapKey @_rafaeltoledo
  • 93. // Fornecendo dependências no módulo @Provides(type = Type.MAP) @GroupKey("um") String provideFirstValue() { return "primeiro valor"; } @Provides(type = Type.MAP) @GroupKey("dois") String provideSecondValue() { return "segundo valor"; } @MapKey @_rafaeltoledo
  • 94. // Uso @Inject Map<String, String> map; // {um=primeiro valor, dois=segundo valor} Por enquanto, só aceita Map e Set, e valores do tipo String e Enumeradores @MapKey @_rafaeltoledo
  • 95. Ok! Tudo muito bonito mas... @_rafaeltoledo
  • 96. O que eu ganho de fato com tudo isso? @_rafaeltoledo
  • 97. Grandes benefícios ● Código mais limpo e organizado ● Melhorias no gerenciamento de objetos (melhor controle de singletons) ● Código mais fácil de TESTAR @_rafaeltoledo
  • 98. Dagger 2 e Testes ● Programar orientado a interfaces - mocks ● Sobrescrita de Componentes e Módulos @_rafaeltoledo
  • 99. Dagger 2 e Testes @Module public class TestMainModule { @Provides // Poderíamos fazer com o Retrofit Mock! public ApiService provideApiService() { return new ApiService() { @Override public List<Repo> listRepos() { return Arrays.asList( new Repo("my-test-repo"), new Repo("another-test-repo") ); } }; } } @_rafaeltoledo
  • 100. Dagger 2 e Testes @Component(modules = DebugMainModule.class) public interface TestMainComponent extends MainComponent { } @_rafaeltoledo
  • 101. Dagger 2 e Espresso 2 @RunWith(AndroidJUnit4.class) public class MainActivityTest { // ... @Before public void setUp() { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); MainApplication app = (MainApplication) instrumentation.getTargetContext().getApplicationContext(); app.setComponent(DaggerDebugMainComponent.create()); rule.launchActivity(new Intent()); } } @_rafaeltoledo
  • 102. Dagger 2 e Robolectric 3 @RunWith(RobolectricGradleTestRunner.class) @Config(sdk = 21, constants = BuildConfig.class) public class MainActivityTest { // ... @Before public void setUp() { MainComponent component = DaggerDebugMainComponent.create(); MainApplication app = ((MainApplication) RuntimeEnvironment.application) .setComponent(component); } } @_rafaeltoledo
  • 104. Para saber mais ● Site oficial - google.github.io/dagger ● Dagger 2 - A New Type of Dependency Injection (Gregory Kick) - vai.la/fdwt ● The Future of Dependency Injection with Dagger 2 (Jake Wharton) - vai.la/fdwy ● froger_mcs Dev Blog - frogermcs.github.io
  • 105. OBRIGADO! rafaeltoledo.net @_rafaeltoledo Desenv. Android @ Concrete Solutions concretesolutions.com.br/carreira