Как зарегистрировать декорированные объекты в структурах Dependency Injection (PicoContainer)? - PullRequest
3 голосов
/ 18 декабря 2009

Я хочу обернуть несколько классов, реализующих интерфейс Job, в объект JobEnabledDecorator, который определяет, будет ли он выполняться.

У меня проблемы с выяснением, как настроить это в PicoContainer, чтобы он знал, как создать объекты реализации Job с обертыванием их JobEnabledDecorator.

Возможно ли это в структурах внедрения зависимостей?

Возможно ли это в PicoContainer?

Если так, любая помощь будет оценена.

1 Ответ

7 голосов
/ 18 декабря 2009

Возможно, вы захотите добавить «поведение». Коротко говоря, вам нужно зарегистрировать фабрику поведения, которая создает поведения, которые обертывают ваши адаптеры компонентов. Проще описать этот пример, пройдясь по примеру.

Сначала вы хотите создать контейнер, что-то вроде этого.

final MutablePicoContainer container = new PicoBuilder()
    .withBehaviors(new JobEnabledDecorating())
    .build();

Это означает, что после создания базового объекта - в вашем случае Job - вы хотите добавить к нему что-то дополнительное. Есть несколько встроенных поведений, но вы хотите свой собственный: JobEnabledDecorating.

public class JobEnabledDecorating extends AbstractBehaviorFactory {
    @Override
    public ComponentAdapter createComponentAdapter(
        final ComponentMonitor componentMonitor, final LifecycleStrategy lifecycleStrategy,
        final Properties componentProperties, final Object componentKey,
        final Class componentImplementation, final Parameter... parameters) throws PicoCompositionException 
    {
        return componentMonitor.newBehavior(
            new JobEnabledDecorated(
                super.createComponentAdapter(
                    componentMonitor, lifecycleStrategy, componentProperties, 
                    componentKey, componentImplementation, parameters
                )
            )
        );
    }
}

Фабрика создает поведение JobEnabledDecorated, оборачивая адаптер компонента, который, в свою очередь, предоставляет ваши экземпляры. Настоящая работа теперь выполняется в этом поведении.

public class JobEnabledDecorated extends AbstractBehavior<Job> {
    public JobEnabledDecorated(final ComponentAdapter<Job> delegate) {
        super(delegate);
    }

    @Override
    public Job getComponentInstance(final PicoContainer container, final Type into)
            throws PicoCompositionException {
        final Job instance = super.getComponentInstance(container, into);
        return new JobEnabledDecorator(instance);
    }

    @Override
    public String getDescriptor() {
        return "JobEnabledDecorator-";
    }
}

getComponentInstance запрашивает задание, добавляет декоратор и возвращает этот обернутый объект как новый экземпляр. Вы должны будете добавить свою собственную логику здесь.

public interface Job {
    void execute();
}

public class JobEnabledDecorator implements Job {
    private Job delegate;

    public JobEnabledDecorator(final Job delegate) {
        this.delegate = delegate;
    }

    @Override
    public void execute() {
        System.out.println("before");
        delegate.execute();
        System.out.println("after");
    }
}

public class MyJob implements Job {
    @Override
    public void execute() {
        System.out.println("execute");
    }
}

Вернемся к нашему использованию контейнера, рассмотрим этот пример.

    final MutablePicoContainer container = new PicoBuilder()
        .withBehaviors(new JobEnabledDecorating())
        .build();

    container.addComponent(Job.class, MyJob.class);

    final Job job = container.getComponent(Job.class);
    job.execute();

Запуск этого будет печатать:

before
execute
after

Это, конечно, потому что контейнер вручил вам JobEnabledDecorator(MyJob) объект.

...