The power of the ContextResolver Part I
How to use a ContextResolver? What can you do with this?
Let´s say you have something like the following:
The implementation DemoLogicB is a normal JavaClass, KotlinDemoLogic is writen in Kotlin. Both implementations are paired with a qualifier and a producer like the following in the picture.
At this point you have n implementations with n qualiefiers and maybe n producer. Or it must be possible to extend the running system with a few more different customer dependent implementations. To write this inside your code with an big if else tree it is not a good style. From the busineslogic point of view the right definition is:
For this you can use the producer methods from cdi. The way is quite easy:
Now we have to implement the first class, called DemoContextResolver. The DemoContextResolver will be injected into every producer that must be able to decide something.
Let´s say you have something like the following:
@Inject @DemoLogicContext DemoLogic demologic;But it depends on the transient context of the application to decide what is the right implementation of the interface DemoLogic.
The implementation DemoLogicB is a normal JavaClass, KotlinDemoLogic is writen in Kotlin. Both implementations are paired with a qualifier and a producer like the following in the picture.
At this point you have n implementations with n qualiefiers and maybe n producer. Or it must be possible to extend the running system with a few more different customer dependent implementations. To write this inside your code with an big if else tree it is not a good style. From the busineslogic point of view the right definition is:
@Inject @DemoLogicContext DemoLogic demologic;
For this you can use the producer methods from cdi. The way is quite easy:
@Produces @DemoLogicContext public DemoLogic create(){...}With this you have the entry-point for the final injection point. You can extend the signature of the create method with more attributes. Mostly used is the BeanManager and/or InjectioPoint, but you can use your own classes. For example the ContextResolver.
@Produces @DemoLogicContext public DemoLogic create(ContextResolver contextResolver){...}The ContextResolver itself is an interface.. this means you have to use an qualifier to define the producer or implementing class for this interface.
@Produces @DemoLogicContext public DemoLogic create(@DemoLogicContext ContextResolver contextResolver){...}
Now we have to implement the first class, called DemoContextResolver. The DemoContextResolver will be injected into every producer that must be able to decide something.
public class DemoLogicProducer { private @Inject ManagedInstanceCreator creator; @Produces @DemoLogicContext public DemoLogic create(@New DemoContextResolver contextResolver){ final ClassFrom this point you are able to decide what will be the implementation to use. For this example I wrote a very simple version, but you can extend this to a tree of deciding ContextResolvers.beanType = DemoLogic.class; final AnnotationLiteral annotationLiteral = contextResolver.resolveContext(beanType); final DemoLogic demoLogic = creator.getManagedInstance(beanType, annotationLiteral); return demoLogic; } }
public class DemoContextResolver implements ContextResolver { @Inject DemoContext demoContext; @Override public AnnotationLiteral resolveContext(Class targetClass) { if(demoContext.getContextInfo()){ return new AnnotationLiteralThe good thing is, that every module will be usable for itself. You can write jUnit-Tests per implementation. At runtime you can add more implementations. Think about the possibility to change the controller for a GUI in this way ;-) I will show this more in detail in my next blog entry (Part II)() {}; } else{ return new AnnotationLiteral () {}; } } }
Kommentare
Kommentar veröffentlichen