-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public interface Container { | ||
|
||
void useFactory(Object factory); | ||
void useFactory(Class factory); | ||
void register(Object something); | ||
void register(Class something); | ||
|
||
<T> T provide(Class<T> type); | ||
|
||
boolean supports(Class type); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package br.com.caelum.sioc; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class CuteContainer implements Container { | ||
|
||
private final List<Provider> providers = new ArrayList<Provider>(); | ||
|
||
public CuteContainer(Container container) { | ||
providers.add(new ParentProvider(container)); | ||
} | ||
|
||
public CuteContainer() { | ||
} | ||
|
||
@Override | ||
public void register(Object something) { | ||
providers.add(new FixedProvider(something)); | ||
} | ||
|
||
@Override | ||
public <T> T provide(Class<T> type) { | ||
return (T) providerFor(type).provide(type); | ||
} | ||
|
||
private <T> Provider<T> providerFor(Class<T> type) { | ||
for(Provider provider : providers) { | ||
if(provider.supports(type)) { | ||
return provider; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean supports(Class type) { | ||
for(Provider provider : providers) { | ||
if(provider.supports(type)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public void useFactory(Object factory) { | ||
register(factory); | ||
registerFactoryMethodsFor(factory.getClass()); | ||
} | ||
|
||
@Override | ||
public void useFactory(Class factory) { | ||
register(factory); | ||
registerFactoryMethodsFor(factory); | ||
} | ||
|
||
private void registerFactoryMethodsFor(Class factory) { | ||
for(Method m : factory.getDeclaredMethods()) { | ||
if(!m.getReturnType().equals(Void.class)) { | ||
providers.add(new FactoryProvider(this, factory, m)); | ||
} | ||
} | ||
} | ||
@Override | ||
public void register(Class something) { | ||
providers.add(new InstantiateOnce(something)); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package br.com.caelum.sioc; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
public class FactoryProvider implements Provider { | ||
|
||
private final Class factory; | ||
private final Method m; | ||
private final Container container; | ||
|
||
public FactoryProvider(Container container, | ||
Class factory, Method m) { | ||
this.container = container; | ||
this.factory = factory; | ||
this.m = m; | ||
} | ||
|
||
@Override | ||
public Object provide(Class type) { | ||
try { | ||
return m.invoke(container.provide(factory)); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean supports(Class type) { | ||
return type.isAssignableFrom(m.getReturnType()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public class FixedProvider<T> implements Provider<T> { | ||
|
||
private final T instance; | ||
|
||
public FixedProvider(T what) { | ||
this.instance =what; | ||
} | ||
|
||
@Override | ||
public T provide(Class type) { | ||
return instance; | ||
} | ||
|
||
@Override | ||
public boolean supports(Class<T> type) { | ||
return type.isAssignableFrom(instance.getClass()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public class InstantiateOnce implements Provider { | ||
|
||
private final Class something; | ||
private Object instance; | ||
|
||
public InstantiateOnce(Class something) { | ||
this.something = something; | ||
} | ||
|
||
@Override | ||
public Object provide(Class type) { | ||
if (this.instance == null) { | ||
try { | ||
instance = something.newInstance(); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
return instance; | ||
} | ||
|
||
@Override | ||
public boolean supports(Class type) { | ||
return type.isAssignableFrom(something); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public class ParentProvider implements Provider { | ||
|
||
private final Container container; | ||
|
||
public ParentProvider(Container container) { | ||
this.container = container; | ||
} | ||
|
||
@Override | ||
public Object provide(Class type) { | ||
return container.provide(type); | ||
} | ||
|
||
@Override | ||
public boolean supports(Class type) { | ||
return container.supports(type); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public interface Provider<T> { | ||
|
||
Object provide(Class type); | ||
|
||
boolean supports(Class<T> type); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package br.com.caelum.sioc; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import java.util.Calendar; | ||
import java.util.GregorianCalendar; | ||
|
||
import org.junit.Test; | ||
|
||
public class CuteContainerTest { | ||
|
||
@Test | ||
public void shouldReturnObjectThatWasRegistered() { | ||
Container container = new CuteContainer(); | ||
container.register(new DefaultEmailSender()); | ||
DefaultEmailSender provided = container.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
@Test | ||
public void shouldReturnInstanceFromTypeIfRegisteringType() { | ||
Container container = new CuteContainer(); | ||
container.register(DefaultEmailSender.class); | ||
DefaultEmailSender provided = container.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
@Test | ||
public void shouldReturnAlwaysTheSameIfTheTypeIsRegistered() { | ||
Container container = new CuteContainer(); | ||
container.register(DefaultEmailSender.class); | ||
assertEquals(container.provide(DefaultEmailSender.class),container.provide(DefaultEmailSender.class)); | ||
} | ||
|
||
@Test | ||
public void shouldAllowContainerReplication() { | ||
Container container = new CuteContainer(); | ||
container.register(new DefaultEmailSender()); | ||
CuteContainer child = new CuteContainer(container); | ||
DefaultEmailSender provided = child.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
static class EmailSenderFactory { | ||
public DefaultEmailSender sender() { | ||
return new DefaultEmailSender(); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldAllowRegisteringFactoryInstance() { | ||
Container container = new CuteContainer(); | ||
container.useFactory(new EmailSenderFactory()); | ||
DefaultEmailSender provided = container.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
@Test | ||
public void shouldAllowRegisteringFactoryType() { | ||
Container container = new CuteContainer(); | ||
container.useFactory(EmailSenderFactory.class); | ||
DefaultEmailSender provided = container.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
static class AppConfig { | ||
Integer base() { | ||
return 1; | ||
} | ||
} | ||
|
||
static class RequestConfig { | ||
private final Integer base; | ||
public RequestConfig(Integer base) { | ||
this.base = base; | ||
} | ||
|
||
public Double anExtraHalf() { | ||
return this.base+0.5; | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldAcceptInjection() { | ||
Container container = new CuteContainer(); | ||
container.useFactory(EmailSenderFactory.class); | ||
DefaultEmailSender provided = container.provide(DefaultEmailSender.class); | ||
assertEquals(DefaultEmailSender.class, provided.getClass()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package br.com.caelum.sioc; | ||
|
||
public class DefaultEmailSender { | ||
|
||
} |