Создание простого контейнера внедрения зависимостей в Java, динамическое создание объектов - PullRequest
2 голосов
/ 22 февраля 2012

Я хочу создать простой контейнер внедрения зависимостей в Java. Что-то, что я могу использовать следующим образом:

DI.register(ITheInterface, ClassImplementingInterface);
obj = DI.create(ITheInterface);

Как может выглядеть реальный код, реализующий register & create?

UPDATE

Почему я пытаюсь понять ссылку, предоставленную @Bill, я хочу понять, что не так с моей попыткой:

public class Container {

    protected static Container instance;
    protected Hashtable<Class<?>, Class<?>> classMap;

    protected Container() {
        this.classMap = new Hashtable<Class<?>, Class<?>>();
    }

    public static Container getInstance() {
        if (Container.instance == null)
            Container.instance = new Container();
        return Container.instance;
    }

    public void register(Class<?> forInterface, Class<?> toUse) {
        this.classMap.put(forInterface, toUse);
    }

    public Object create(Class<?> forInterface) throws Exception {
        if (!this.classMap.containsKey(forInterface))
            throw new Exception("Dependency Ingection Container does not have a class registered for use with " + forInterface.getName());
        return this.classMap.get(forInterface).newInstance();
    }
}

Тестовый код:

interface ITest {
    public String getName();
    public void setName(String name);
}

class Test1 implements ITest {

    protected String name;

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

}

public class Test {
    public static void main(String[] args) throws Exception {
        Container di = Container.getInstance();
        di.register(ITest.class, Test1.class);
        ITest t1 = (ITest)di.create(ITest.class);
        t1.setName("Yay!!!");
        System.out.println(t1.getName());
    }
}

Ошибка, которую я получил:

Exception in thread "main" java.lang.IllegalAccessException: Class dependencyinjection.Container can not access a member of class Test1 with modifiers ""
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95)
    at java.lang.Class.newInstance0(Class.java:366)
    at java.lang.Class.newInstance(Class.java:325)
    at dependencyinjection.Container.create(Container.java:27)
    at Test.main(Test.java:32)

ОБНОВЛЕНИЕ 2

Я полагал, что это будет работать, когда я сделаю класс public. Есть еще одна проблема, я хочу создать классы на основе универсальных интерфейсов. например.

  • IDataMapper<Event> ==> EventDataMapper
  • IDataMapper<Venue> ==> VenueDataMapper

В настоящее время, если я делаю

di.register(IDataMapper<Event>.class, EventDataMapper.class);

Я получаю IDataMapper и Event не разрешены в переменную

1 Ответ

3 голосов
/ 22 февраля 2012

Вы можете найти простую реализацию JSR 330 здесь

Это довольно легко понять.

Чтобы ответить на ваши правки:

Test1 - это закрытый класс пакета. Контейнер в другом пакете не имеет доступа к конструктору Test1. Вы можете обойти это, выполнив следующие действия:

Constructor c = this.classMap.get(forInterface).getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...