-
Notifications
You must be signed in to change notification settings - Fork 998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaDependencyInjection #1001
base: main
Are you sure you want to change the base?
JavaDependencyInjection #1001
Changes from 4 commits
0d67326
53cd600
03a53f1
e503d73
c789aaa
5a09b0e
3f94cf8
2b1ec9c
2e0e090
45cd671
b493b07
856a733
d6dc2c8
78ea73e
4c13282
e8b95d3
7098a7c
5e7ab09
e203ab6
2b29161
3885bd4
b2265bd
e51f181
228b388
1c88d9a
7e19762
287c2a0
3b54686
063f2d1
10418ed
a7c7248
a48cf47
416e7ee
95706d6
99310cc
79a082c
7890514
ee629d1
8be9221
981fa13
8b88d9e
c42aefb
85fed85
6946bad
f1f5813
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
package mate.academy.lib; | ||
|
||
public @interface Component { | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Component { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
package mate.academy.lib; | ||
|
||
public @interface Inject { | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add target |
||
public @interface Inject { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,61 @@ | ||
package mate.academy.lib; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class Injector { | ||
private static final Injector injector = new Injector(); | ||
private final Map<Class<?>, Object> instances = new HashMap<>(); | ||
|
||
public static Injector getInjector() { | ||
return injector; | ||
} | ||
|
||
public Object getInstance(Class<?> interfaceClazz) { | ||
return null; | ||
if (!interfaceClazz.isInterface()) { | ||
throw new RuntimeException("Only interfaces are supported"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The exception message could be more informative. According to the checklist, when throwing an exception, it should contain an informative message. Consider including the type of the class that is not an interface. |
||
} | ||
|
||
Class<?> implClass = findImplementation(interfaceClazz); | ||
if (implClass == null || !implClass.isAnnotationPresent(Component.class)) { | ||
throw new RuntimeException("No implementation found for " + interfaceClazz.getName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The exception message should be more informative and include the reason why the implementation wasn't found. According to the checklist, the message should indicate the missing |
||
} | ||
|
||
return createInstance(implClass); | ||
} | ||
|
||
private Class<?> findImplementation(Class<?> interfaceClazz) { | ||
// This method should return the implementation class for the given interface | ||
// For simplicity, let's assume we have a hardcoded map of implementations | ||
Map<Class<?>, Class<?>> implementations = Map.of( | ||
ProductService.class, ProductServiceImpl.class, | ||
ProductParser.class, ProductParserImpl.class, | ||
FileReaderService.class, FileReaderServiceImpl.class | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The implementations map should be a class field instead of being created in the |
||
); | ||
return implementations.get(interfaceClazz); | ||
} | ||
|
||
private Object createInstance(Class<?> implClass) { | ||
if (instances.containsKey(implClass)) { | ||
return instances.get(implClass); | ||
} | ||
|
||
try { | ||
Object instance = implClass.getDeclaredConstructor().newInstance(); | ||
instances.put(implClass, instance); | ||
|
||
for (Field field : implClass.getDeclaredFields()) { | ||
if (field.isAnnotationPresent(Inject.class)) { | ||
field.setAccessible(true); | ||
Object fieldInstance = getInstance(field.getType()); | ||
field.set(instance, fieldInstance); | ||
} | ||
} | ||
|
||
return instance; | ||
} catch (ReflectiveOperationException e) { | ||
throw new RuntimeException("Failed to create instance of " + implClass.getName(), e); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of catching multiple exceptions separately, it's recommended to catch their common parent, |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the checklist, custom annotations should have a
@Target
annotation to specify where this annotation can be used. For example, if@Component
is meant to be used on classes, you should add@Target(ElementType.TYPE)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the checklist, custom annotations should have a @target annotation to specify where this annotation can be used. For example, if @component is meant to be used on classes, you should add @target(ElementType.TYPE).