Using Guice,I would like create three different instances for my Color class i.e BLUE, RED, YELLOW and want to bind different color value... but I am not understanding how to bind different value per instance...
For the below sample code, if you see, I would like to use same ColorClass implementation for all three colors Instances(named as "BLUE","RED","ORANGE") by passing different color as String variable.
public interface ColorInterface {
public String getMeColor()
}
Sample implementation....
public class ColorClass implements ColorInterface {
#Inject #Named("color")
String color
public String getMeColor(){
return color
}
}
Sample binding........
public class ColorModule extends AbstractModule {
#Override
protected void configure() {
bind(ColorInterface.class).annotatedWith(Names.named("BLUE")).to(ColorClass.class);
bind(ColorInterface.class).annotatedWith(Names.named("RED")).to(ColorClass.class);
bind(ColorInterface.class).annotatedWith(Names.named("ORANGE")).to(ColorClass.class);
......
}
}
Please help me...
If this directly is your issue, I would suggest a slight change in the implementation to move the injected #Named("color") String into a constructor argument and the use of a custom Provider:
public class ColorClass implements ColorInterface {
String color;
ColorClass(String color) {
this.color = color;
}
public String getMeColor(){
return color;
}
public static Provider implements Provider<ColorClass> {
String color;
public Provider(String color) {
this.color = color;
}
public ColorClass get() {
return new ColorClass(color);
}
}
}
and then in your module:
public class ColorModule extends AbstractModule {
#Override
protected void configure() {
bind(ColorInterface.class).annotatedWith(Names.named("BLUE"))
.toProvider(new ColorClass.Provider("Blue"));
bind(ColorInterface.class).annotatedWith(Names.named("RED"))
.toProvider(new ColorClass.Provider("Red"));
bind(ColorInterface.class).annotatedWith(Names.named("ORANGE"))
.toProvider(new ColorClass.Provider("Orange"));
}
}
Obviously, the Provider doesn't need to be a static inner class like I did there, just something in the same package.
In case this exact problem isn't really your problem and you really do need #Named("color") String to be differently injected (say, you've actually got some really deep nested structure pulled together with guice and need a different binding deep in the hierarchy, and can't easily refactor that into a constructor parameter), then you'll need to use private modules.
However, that technique is vast overkill for the case you presented, so I'm hesitant to dive into it here. It's really a rather advanced topic you shouldn't try to tackle unless you really need to solve the problem it solves. (The problem is sometimes referred to as the "Robot Arms" problem)
Related
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;
}
I am creating an android app and I write following classes and interface and codes .Because I try to use MVP pattern , But now I am not sure that my codes are standard or not ?
should I use Dagger2 for Di or should not?
model , presenter class are below:
public class ChangePasswordModel{
public void saveChange(final String oldPass, final String newPass, final ChangePasswordCallback callback) {
/*in real world it change password with API*/
callback.onDo();
} }
my presenter is :
public class ChangePasswordPresenter{
private ChangePasswordContract.View mView;//this is an interface to interact with Activity
public ChangePasswordPresenter(ChangePasswordContract.View mView) {
this.mView = mView;
}
public void pSaveChange(String oldPass, String newPass) {
ChangePasswordModel model = new ChangePasswordModel();
model.saveChange(oldPass, newPass, new ChangePasswordCallback() {
#Override
public void onDo() {
mView.showMessage("password Changed");
}
});
}
}
Do I implemented MVP correctly?
Should I use Dagger2 for DI? why?
The sample codes that you mentioned in your question is a correct implementation of MVP which can get improved by some changes.
The best practice is a mixture of Dagger, MVP, RxJava, Retrofit and Mock tests which improve the quality and readability of your project. MVP helps you with a clean and separate layered code and RxJava will help with wiring different layers up together and Dagger2 can really helps you with managing dependencies and also make your Mocking in test easy.
You can take a look at this sample project repo on my Github which has been developed using Dagger, MVP and there are also some test available:
http://github.com/mmirhoseini/fyber_mobile_offers
It needs to be improved in my opinion. You Model class must be a concrete object class however your ChangePasswordModel contains saveChange() method that have no idea why it's calling a callback. This logic must be implemented in Presenter class.
Basically process of following MVP design pattern is as follows:
create a package based on your screen. Let's say you have a Signup screen. Then create a package, <your.main.package>.signupscreen.
Create three classes of SignupActivity, SignupView(this is interface), SignupPresenter.
SignupView interface:
interface SignUpView {
String getFirstName();
String getLastName();
String getEmailAddress();
String getPassword();
}
SignupActivity implements SignUpView and holds a reference of SignupPresenter.
public class SignUpActivity implements SignUpView {
#Inject
public Service mService;
SignUpPresenter mSignUpPresenter;
#Override
protected void onStart() {
super.onStart();
mSignUpPresenter = new SignUpPresenter(mService, this);
}
#Override
protected void onStop() {
super.onStop();
if (mSignUpPresenter != null) {
mSignUpPresenter.onStop();
}
}
#Override
public String getFirstName() {
return etFirstName.getText().toString().trim();
}
#Override
public String getLastName() {
return etLastName.getText().toString().trim();
}
#Override
public String getEmailAddress() {
return etEmail.getText().toString().trim();
}
#Override
public String getPassword() {
return etPassword.getText().toString().trim();
}
}
And finally SignupPresenter class:
class SignUpPresenter implements SignUpCallback {
private final Service service;
private final SignUpView view;
private CompositeSubscription subscriptions;
SignUpPresenter(Service service, SignUpView view) {
this.service = service;
this.view = view;
this.subscriptions = new CompositeSubscription();
}
void onStop() {
subscriptions.unsubscribe();
}
}
This is very basic implementation of Activity based on MVP. I do recommend to have a look at this awesome doc regard MVP, Retrofit and Dagger 2, A Simple Android Apps with MVP, Dagger, RxJava, and Retrofit
I'd like to vary the injected implementations based on something that's not known until runtime. Specifically, I'd like my app to operate as different versions where the "version" is not determined until a request is executing. Also, the "version" could vary per request.
After reading the docs it seems that I could implement a providers in cases where I need to choose an implementation at runtime based on the "version". Additionally, I could roll my own on top of juice.
Is implementing a provider the best way to go in this scenario? I'd like to know if there is a best practice or if anyone else out there has tried to use Guice to tackle this problem.
Thanks for any help!
-Joe
I think that if the version can be known only at runtime, you must provide the versioned "services" manually with custom provider. Possibly something like this:
#Singleton
public abstract class VersionedProvider<T, V> {
private Map<V, T> objects;
T get(V version) {
if (!objects.containsKey(version)) {
objects.put(version, generateVersioned(version));
}
return objects.get(version);
}
// Here everything must be done manually or use some injected
// implementations
public abstract T generateVersioned(V version);
}
public class MyRuntimeServiceModule extends AbstractModule {
private final String runTimeOption;
public ServiceModule(String runTimeOption) {
this.runTimeOption = runTimeOption;
}
#Override protected void configure() {
Class<? extends Service> serviceType = option.equals("aServiceType") ?
AServiceImplementation.class : AnotherServiceImplementation.class;
bind(Service.class).to(serviceType);
}
}
public static void main(String[] args) {
String option = args[0];
Injector injector = Guice.createInjector(new MyRuntimeServiceModule(option));
}
I have a command class that needs to have 2 constructors. However,
using structuremap it seems that I can only specify one constructor to
be used. I have solved the problem for now by subtyping the specific
command class, which each implementation implementing it's own
interface and constructor. Like the code below shows. The
ISelectCommand implements two separate interfaces for the
string constructor and the int constructor, just for the sake of
registering the two subtypes using structuremap.
However, I consider this a hack and I just wonder why is it not
possible for structuremap to resolve the constructor signature by the
type passed in as parameter for the constructor? Then I could register
the SelectProductCommand as an ISelectCommand and
instantiate it like:
ObjectFactury.With(10).Use>();
orObjectFactury.With("testproduct").Use>();
public class SelectProductCommand : ISelectCommand<IProduct>,
ICommand, IExecutable
{
private readonly Func<Product, Boolean> _selector;
private IEnumerable<IProduct> _resultList;
public SelectProductCommand(Func<Product, Boolean> selector)
{
_selector = selector;
}
public IEnumerable<IProduct> Result
{
get { return _resultList; }
}
public void Execute(GenFormDataContext context)
{
_resultList = GetProductRepository().Fetch(context,
_selector);
}
private Repository<IProduct, Product> GetProductRepository()
{
return ObjectFactory.GetInstance<Repository<IProduct,
Product>>();
}
}
public class SelectProductIntCommand: SelectProductCommand
{
public SelectProductIntCommand(Int32 id): base(x =>
x.ProductId == id) {}
}
public class SelectProductStringCommand: SelectProductCommand
{
public SelectProductStringCommand(String name): base(x =>
x.ProductName.Contains(name)) {}
}
P.s. I know how to tell structuremap what constructor map to use, but my again my question is if there is a way to have structuremap select the right constructor based on the parameter passed to the constructor (i.e. using regular method overloading).
The short answer is this post by the creator of Structuremap.
The long answer is regarding the structure you have in that piece of code. In my view, a command is by definition a "class" that does something to an "entity", i.e it modifies the class somehow. Think CreateNewProductCommand.
Here you are using commands for querying, if I'm not mistaken. You also have a bit of a separation of concern issue floating around here. The command posted defines what to do and how to do it, which is to much and you get that kind of Service location you're using in
private Repository<IProduct, Product> GetProductRepository()
{
return ObjectFactory.GetInstance<Repository<IProduct, Product>>();
}
The way I'd structure commands is to use CreateProductCommand as a data contract, i.e it only contains data such as product information.
Then you have a CreateProductCommandHandler which implements IHandles<CreateProductCommand> with a single method Handle or Execute. That way you get better separation of concern and testability.
As for the querying part, just use your repositores directly in your controller/presenter, alternatively use the Query Object pattern
I think I solved the problem using a small utility class. This class gets the concrete type from ObjectFactory and uses this type to construct the instance according to the parameters past into the factory method. Now on the 'client' side I use ObjectFactory to create an instance of CommandFactory. The implementation of CommandFactory is in another solution and thus the 'client solution' remains independent of the 'server' solution.
public class CommandFactory
{
public ICommand Create<T>()
{
return Create<T>(new object[] {});
}
public ICommand Create<T>(object arg1)
{
return Create<T>(new[] {arg1});
}
public ICommand Create<T>(object arg1, object arg2)
{
return Create<T>(new[] {arg1, arg2});
}
public ICommand Create<T>(object arg1, object arg2, object arg3)
{
return Create<T>(new[] {arg1, arg2, arg3});
}
public ICommand Create<T>(object[] arguments)
{
return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments);
}
public static Type GetRegisteredType<T>()
{
return ObjectFactory.Model.DefaultTypeFor(typeof (T));
}
}
How do I handle classes with static methods with Ninject?
That is, in C# one can not have static methods in an interface, and Ninject works on the basis of using interfaces?
My use case is a class that I would like it to have a static method to create an
unpopulated instance of itself.
EDIT 1
Just to add an example in the TopologyImp class, in the GetRootNodes() method, how would I create some iNode classes to return? Would I construct these with normal code practice or would I somehow use Ninject? But if I use the container to create then haven't I given this library knowledge of the IOC then?
public interface ITopology
{
List<INode> GetRootNodes();
}
public class TopologyImp : ITopology
{
public List<INode> GetRootNodes()
{
List<INode> result = new List<INode>();
// Need code here to create some instances, but how to without knowledge of the container?
// e.g. want to create a few INode instances and add them to the list and then return the list
}
}
public interface INode
{
// Parameters
long Id { get; set; }
string Name { get; set; }
}
class NodeImp : INode
{
public long Id
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
// Just background to highlight the fact I'm using Ninject fine to inject ITopology
public partial class Form1 : Form
{
private ITopology _top;
public Form1()
{
IKernel kernal = new StandardKernel(new TopologyModule());
_top = kernal.Get<ITopology>();
InitializeComponent();
}
}
If you're building a singleton or something of that nature and trying to inject dependencies, typically you instead write your code as a normal class, without trying to put in lots of (probably incorrect) code managing the singleton and instead register the object InSingletonScope (v2 - you didnt mention your Ninject version). Each time you do that, you have one less class that doesnt surface its dependencies.
If you're feeling especially bloody-minded and are certain that you want to go against that general flow, the main tools Ninject gives you is Kernel.Inject, which one can use after you (or someone else) has newd up an instance to inject the dependencies. But then to locate one's Kernelm you're typically going to be using a Service Locator, which is likely to cause as much of a mess as it is likely to solve.
EDIT: Thanks for following up - I see what you're after. Here's a hacky way to approximate the autofac automatic factory mechanism :-
/// <summary>
/// Ugly example of a not-very-automatic factory in Ninject
/// </summary>
class AutomaticFactoriesInNinject
{
class Node
{
}
class NodeFactory
{
public NodeFactory( Func<Node> createNode )
{
_createNode = createNode;
}
Func<Node> _createNode;
public Node GenerateTree()
{
return _createNode();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToMethod( context => () => Kernel.Get<Node>() );
}
}
[Fact]
public void CanGenerate()
{
var kernel = new StandardKernel( new Module() );
var result = kernel.Get<NodeFactory>().GenerateTree();
Assert.IsType<Node>( result );
}
}
The ToMethod stuff is a specific application of the ToProvider pattern -- here's how you'd do the same thing via that route:-
...
class NodeProvider : IProvider
{
public Type Type
{
get { return typeof(Node); }
}
public object Create( IContext context )
{
return context.Kernel.Get<Node>();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToProvider<NodeProvider>();
}
}
...
I have not thought this through though and am not recommending this as A Good Idea - there may be far better ways of structuring something like this. #Mark Seemann? :P
I believe Unity and MEF also support things in this direction (keywords: automatic factory, Func)
EDIT 2: Shorter syntax if you're willing to use container-specific attributes and drop to property injection (even if Ninject allows you to override the specific attributes, I much prefer constructor injection):
class NodeFactory
{
[Inject]
public Func<Node> NodeFactory { private get; set; }
public Node GenerateTree()
{
return NodeFactory();
}
}
EDIT 3: You also need to be aware of this Ninject Module by #Remo Gloor which is slated to be in the 2.4 release
EDIT 4: Also overlapping, but not directly relevant is the fact that in Ninject, you can request an IKernel in your ctor/properties and have that injected (but that doesn't work directly in a static method).