Guice - How to use binding annotations to build a list of objects - dependency-injection

I have created Guice binding annotations that allow me to bind two different instances of a class depending on the annotation e.g.:
bind(Animal.class).withAnnotation(Cat.class).toInstance(new Animal("Meow"));
bind(Animal.class).withAnnotation(Dog.class).toInstance(new Animal("Woof"));
I was hoping to be able to create a provider method that provides a List that is a dependency for one of my classes, but can't figure out how to use the annotations for this:
#Provider
List<Animal> provideAnimalList() {
List<Animal> animals = new ArrayList<Animal>();
animals.add(#Cat Animal.class); // No, but this is what I want
animals.add(#Dog Animal.class); // No, but this is what I want
return animals;
}
So I was assuming that I would just be able to use the annotations in the argument to add() method of the List... but no.
How should I be approaching this? It seems to me it would be simpler simply to new the two instances of the Animal class and maybe this is not how the binding annotations were meant to be used.
I'd appreciate comments on the best use of the binding annotations in this scenario.
Thanks

If it is really what you want, here a working solution :
public class AnimalModule extends AbstractModule {
#Override
protected void configure() {
bind(Animal.class).annotatedWith(Cat.class).toInstance(new Animal("Meow"));
bind(Animal.class).annotatedWith(Dog.class).toInstance(new Animal("Woof"));
}
#Provides
List<Animal> provideAnimalList(#Cat Animal cat, #Dog Animal dog) {
List<Animal> animals = new ArrayList<Animal>();
animals.add(cat);
animals.add(dog);
return animals;
}
public static void main(String[] args) {
List<Animal> animals = Guice.createInjector(new AnimalModule()).getInstance(Key.get(new TypeLiteral<List<Animal>>() {
}));
for (Animal animal : animals) {
System.out.println(animal);
}
}
}
Annotations :
#Retention(value = RetentionPolicy.RUNTIME)
#BindingAnnotation
public #interface Cat {
}
Output :
Animal{sound='Meow'}
Animal{sound='Woof'}
However :
Don't create specific annotations, seems unnecessary in that case. Use #Named instead,
You may consider Multibindings to solve that problem.

Related

Getting an injected object using CDI Produces

I have a class (OmeletteMaker) that contains an injected field (Vegetable). I would like to write a producer that instantiates an injected object of this class. If I use 'new', the result will not use injection. If I try to use a WeldContainer, I get an exception, since OmeletteMaker is #Alternative. Is there a third way to achieve this?
Here is my code:
#Alternative
public class OmeletteMaker implements EggMaker {
#Inject
Vegetable vegetable;
#Override
public String toString() {
return "Omelette: " + vegetable;
}
}
a vegetable for injection:
public class Tomato implements Vegetable {
#Override
public String toString() {
return "Tomato";
}
}
main file
public class CafeteriaMainApp {
public static WeldContainer container = new Weld().initialize();
public static void main(String[] args) {
Restaurant restaurant = (Restaurant) container.instance().select(Restaurant.class).get();
System.out.println(restaurant);
}
#Produces
public EggMaker eggMakerGenerator() {
return new OmeletteMaker();
}
}
The result I get is "Restaurant: Omelette: null", While I'd like to get "Restaurant: Omelette: Tomato"
If you provide OmeletteMaker yourself, its fields will not be injected by the CDI container. To use #Alternative, don't forget specifying it in the beans.xml and let the container instantiate the EggMaker instance:
<alternatives>
<class>your.package.path.OmeletteMaker</class>
</alternatives>
If you only want to implement this with Producer method then my answer may be inappropriate. I don't think it is possible (with standard CDI). The docs says: Producer methods provide a way to inject objects that are not beans, objects whose values may vary at runtime, and objects that require custom initialization.
Thanks Kukeltje for pointing to the other CDI question in comment:
With CDI extensions like Deltaspike, it is possible to inject the fields into an object created with new, simply with BeanProvider#injectFileds. I tested this myself:
#Produces
public EggMaker eggMakerProducer() {
EggMaker eggMaker = new OmeletteMaker();
BeanProvider.injectFields(eggMaker);
return eggMaker;
}

Creating an interface for construction

A few times now I've run into a use case where I need to define an interface for how classes construct themselves. One such example could be if I want to make an Interface Class that defines the interface by which objects can serialize and unserialize themselves (for input into a database, to be sent as JSON, etc). You might write something like this:
abstract class Serializable {
String serialize();
Serializable unserialize(String serializedString);
}
But now you have a problem, as serialize() is properly an instance method, and unserialize() should instead be a static method (which isn't inheritable or enforced by the Interface) or a constructor (which also isn't inheritable).
This leaves a state where classes that impliment the Serializable interface are required to define a serialize() method, but there is no way to require those classes to define a static unserialize() method or Foo.fromSerializedString() constructor.
If you make unserialize() an instance method, then unserializing an implementing class Foo would look like:
Foo foo = new Foo();
foo = foo.unserialize(serializedString);
which is rather cumbersome and ugly.
The only other option I can think of is to add a comment in the Serializable interface asking nicely that implementing classes define the appropriate static method or constructor, but this is obviously prone to error if a developer misses it and also hurts code completion.
So, is there a better way to do this? Is there some pattern by which you can have an interface which forces implementing classes to define a way to construct themselves, or something that gives that general effect?
You will have to use instance methods if you want the inheritance guarantees. You can do a bit nicer than manual instantiation though, by using reflection.
abstract class Serializable {
static Serializable fromSerializedString(Type type, String serializedString) {
ClassMirror cm = reflectClass(type);
InstanceMirror im = cm.newInstance(const Symbol(''), []);
var obj = im.reflectee;
obj.unserialize(serializedString);
return obj;
}
String serialize();
void unserialize(String serializedString);
}
Now if someone implements Serializable they will be forced to provide an unserialize method:
class Foo implements Serializable {
#override
String serialize() {
// TODO: implement serialize
}
#override
void unserialize(String string) {
// TODO: implement unserialize
}
}
You can get an instance like so:
var foo = Serializable.fromSerializedString(Foo, 'someSerializedString');
This might be a bit prettier and natural than the manual method, but keep in mind that it uses reflection with all the problems that can entail.
If you decide to go with a static method and a warning comment instead, it might be helpful to also provide a custom Transformer that scans through all classes implementing Serializable and warn the user or stops the build if any don't have a corresponding static unserialize method or constructor (similar to how Polymer does things). This obviously wouldn't provide the instant feedback the an editor could with instance methods, but would be more visible than a simple comment in the docs.
I think this example is a more Dart-like way to implement the encoding and decoding. In practice I don't think "enforcing" the decode signature will actually help catch bugs, or improve code quality. If you need to make the decoder types pluggable then you can make the decoders map configurable.
const Map<String,Function> _decoders = const {
'foo': Foo.decode,
'bar': Bar.decode
};
Object decode(String s) {
var obj = JSON.decode(s);
var decoder = _decoders[obj['type']];
return decoder(s);
}
abstract class Encodable {
abstract String encode();
}
class Foo implements Encodable {
encode() { .. }
static Foo decode(String s) { .. }
}
class Bar implements Encodable {
encode() { .. }
static Foo decode(String s) { .. }
}
main() {
var foo = decode('{"type": "foo", "i": 42}');
var bar = decode('{"type": "bar", "k": 43}');
}
A possible pattern I've come up with is to create a Factory class that utilize instance methods in a slightly less awkward way. Something like follows:
typedef Constructable ConstructorFunction();
abstract class Constructable {
ConstructorFunction constructor;
}
abstract class Serializable {
String serialize();
Serializable unserialize(String serializedString);
}
abstract class SerializableModel implements Serializable, Constructable {
}
abstract class ModelFactory extends Model {
factory ModelFactory(ConstructorFunction constructor) {
return constructor();
}
factory ModelFactory.fromSerializedString(ConstructorFunction constructor, String serializedString) {
Serializable object = constructor();
return object.unserialize(serializedString);
}
}
and finally a concrete implementation:
class Foo extends SerializableModel {
//required by Constructable interface
ConstructorFunction constructor = () => new Foo();
//required by Serializable interface
String serialize() => "I'm a serialized string!";
Foo unserialize(String serializedString) {
Foo foo = new Foo();
//do unserialization work here to populate foo
return foo;
};
}
and now Foo (or anything that extends SerializableModel can be constructed with
Foo foo = new ModelFactory.fromSerializedString(Foo.constructor, serializedString);
The result of all this is that it enforces that every concrete class has a method which can create a new instance of itself from a serialized string, and there is also a common interface which allows that method to be called from a static context. It's still creating an extra object whose whole purpose is to switch from static to instance context, and then is thrown away, and there is a lot of other overhead as well, but at least all that ugliness is hidden from the user. Still, I'm not yet convinced that this is at all the best way to achieve this.
I suggest you define the unserialize function as named constructor like so:
abstract class Serializable<T> {
String serialize();
Serializable.unserialize(String serializedString);
}
This eliminates the need of static methods.
A possible implementation could look like this:
import 'dart:convert';
class JsonMap implements Serializable<JsonMap> {
Map map = {};
JsonMap() {
}
String serialize() {
return JSON.encode(map);
}
JsonMap.unserialize(String serializedString) {
this.map = JSON.decode(serializedString);
}
}
You can (de)serialize like so:
JsonMap m = new JsonMap();
m.map = { 'test': 1 };
print(m.serialize());
JsonMap n = new JsonMap.unserialize('{"hello": 1}');
print(n.map);
While testing this, I noticed that Dart will not throw any errors at you if you dont actually implement the methods that your class promises to implement with implements. This might just be a hicc-up with my local Dart, though.

Dart, never allow nested Generics?

I would like to use the nested Generics, like
class Class<List<T>> {
...
}
But always Dart Editor gives me alerts. How should I avoid these alerts?
Well, Dart Editor is right. This code doesn't make any sense. Without further information on what you are trying to do (don't hesitate to update your question), I am assuming you actually mean one of those:
class MyClass<T> {
List<T> listField;
// other stuff
}
Or maybe the list itself should be generic?
void main() {
MyClass<SomeCustomListClass<String>> instance = new MyClass();
}
class MyClass<T extends List<String>> {
T listField;
// ...
}
Or maybe everything has to be generic:
void main() {
MyClass<String, SomeCustomListClass<String>> instance = new MyClass();
}
class MyClass<TElement, TList extends List<TElement>> {
TList listField;
TElement _firstListElement;
// whatever that could be used for
}

How to use Dependency Injection with Static Methods?

Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.

How to pass param to ctor of instance that is created by ObjectFactory

I using StructureMap to create instances of ModuleData
I have many classes that inherit from ModuleData(class A,B,C...) and each of them get Config1 or Config2 in coustructor
In Registry(located in file1.cs) I scan all types of ModuleData.
In Get(lacated in file2.cs) I get the instance.
I want that when ObjectFactory creates Config1/Config2 while creating instance of ModuleData it will pass "param" to Config1/Config2 constructors.
How I can configure structuremap to do this?
P.S. Registry & Get methods are located in different files!!!
Thank you
public class Config1
{
Config1(string param)
{
}
}
public class Config2
{
Config2(string param)
{
}
}
//.....//
public class A : ModuleData
{
A(Config1 c)
{
}
}
public class B : ModuleData
{
A(Config2 c)
{
}
}
//....//
//located in file1.cs
public Registry()
{
Scan(x =>
{
x.TheCallingAssembly();
x.AddAllTypesOf<ModuleData>();
});
ObjectFactory.Initialize(x =>
{
x.For<Config1>().Use<Config1>();
x.For<Config2>().Use<Config2>();
});
}
//....//
//located in file2.cs
public ModuleData Get(object o)
{
var module = o as PageModule;
var t = Type.GetType(string.Format("{0}.{1},{2}", Settings.Namespace, module.Name, Settings.Assembly));
return ObjectFactory.With("param").EqualTo(module.Parameters).GetInstance(t) as ModuleData;
}
I can't think of a good way to do what you want, I think its a bit of a design problem... I think you would have to explain a bit more about why you need to do this for me to help you.
What is a page module? Why is your config objects dependent on it?
Based on your comment, I think what you need is a factory object that creates ModuleData objects for you. Since they are objects it does not make much sense to get them from the container. Think about using a data access technology like Entity Framework, it would not make sense to get those objects from the container. From what I can tell, this is a similar case.

Resources