I defined an interface.
#Local
public interface MessageService {
}
And an implementation.
#Stateless
public class MessageServiceSome implements MessageService {
}
When I tried to inject it into my resource class, I got null.
//#Path("/messages") // I'M NOT GOING TO MAKE THIS STATELESS!!!
public class MessagesResource {
// none of follwoing options works
// leaves the field null
#Inject
//#EJB
//#EJB(beanName = "MessageServiceSome")
private MessageService messageService;
}
How can I solve this?
UPDATE
I think I have to admit that my question is not good enough.
The MessagesResource class was actually a sub resource. I didn't know the difference.
There are two very good threads for this issue.
https://stackoverflow.com/a/36291890/330457
https://stackoverflow.com/a/24670218/330457
One is using ResourceContext and the other is using Inject.
Both threads are saying they work but I only succeeded with #Inject.
With little information provided, you have probably two quick options you can try:
leave #Inject only, if your project/container is CDI enabled
#Inject
private MessageService messageService;
leave #EJB only, do you really need the beanName ?
#EJB
private MessageService messageService;
on of the two should solve the issue.
[UPDATE]
Otherwise have a look at the app server start up log, and see if the bean has been deployed.
Related
I'd like to use BenchmarkDotNet on some legacy code I'm working with right now. It is written in C# Net462.
It is a big, old and complex system and I'd like to Benchmark some methods inside some specific class. Those classes use dependency injection and I'm not sure how I could do it. All the examples I've seen so far are not using any dependency injection.
Does anyone have any ideas or examples I could have a look?
Thank you very much.
You need to create the dependency injection container in the ctor or a method with [GlobalSetup] attribute, resolve the type that you want to benchmark and store it in a field. Then use it in a benchmark and dispose the DI container in a [GlobalCleanup] method.
Pseudocode:
public class BenchmarksDI
{
private IMyInterface _underTest;
private IDependencyContainer _container;
[GlobalSetup]
public void Setup()
{
_container = CallYourCodeThatBuildsDIContainer();
_underTest = _container.Resolve<IMyInterface>();
}
[Benchmark]
public void MethodA() => _underTest.MethodA();
[GlobalCleanup]
public void Cleanup() => _container.Dispose();
}
I have been struggling to get NopCommerce to pick up a registered interface.
This line here
this._connectionService = EngineContext.Current.Resolve<IConnectionService>();
is causing the error
Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.
I have registered the interface in the DependencyRegistrar
builder.RegisterType<ConnectionService>().As<IConnectionService>().InstancePerLifetimeScope();
The issue is that it works when the constructor is called once, but when the constructor is called again the interface has been disposed, the constructor is as seen below -
public ClientHub()
{
this._connectionService = EngineContext.Current.Resolve<IConnectionService>();
}
By default NopCommerce has a lot of registered interface already so I have tried using what looks like a cached version
builder.RegisterType<CustomerActivityService>().As<ICustomerActivityService>()
.WithParameter(ResolvedParameter.ForNamed<ICacheManager>("nop_cache_static"))
.InstancePerLifetimeScope();
But I still get an error when trying to use the ConnectionService like this.
I have tried using multiple different methods on the builder such as
InstancePerHttpRequest();
and
InstancePerDependency();
But it's all being disposed of when the constructor is called a second time, I did head over to the NopCommerce for any help but no luck.
Any guidance / help would be amazing !
public ClientHub()
{
this._connectionService = EngineContext.Current.Resolve<IConnectionService>();
}
well, that may create an issue, you're trying to resolve dependency, but that messed up.
It could be:
private readonly IConnectionService _connectionService
public ClientHub(IConnectionService connectionService)
{
this._connectionService = connectionService;
}
Or either it could be only:
private readonly IConnectionService _connectionService = EngineContext.Current.Resolve<IConnectionService>();
And not in constructor.
I was quite surprised to see that there is no deterministic behavior for the order in which objects get reinjected.
public class Test {
#Inject private Boolean testBool;
#Inject
public void checkNewObject(Boolean testBoolNew) {
if (!testBoolNew.equals(this.testBool)) {
System.out.println("Out of sync!");
} else {
System.out.println("In sync!");
}
}
}
And this is how I use the class:
context.set(Boolean.class, new Boolean(true));
Test test = ContextInjectionFactory.make(Test.class, context);
context.set(Boolean.class, new Boolean(false));
So, sometimes I get the output:
In sync!
In sync!
And sometimes I get:
In sync!
Out of sync!
Is this really non deterministic or am I just overseeing something?
The documentation clearly states that the injection order should be:
Constructor injection: the public or protected constructor annotated with #Inject with the greatest number of resolvable arguments is selected
Field injection: values are injected into fields annotated with #Inject and that have a satisfying type
Method injection: values are injected into methods annotated with #Inject and that have satisfying arguments
See: https://wiki.eclipse.org/Eclipse4/RCP/Dependency_Injection#Injection_Order
I'm not sure, why this doesn't work as expected in your case.
How is equals() implemented in MyContent?
Is MyContent annotated with #Creatable and or #Singleton?
As a side note: Is this a practical or just an academic problem? Why is it necessary to inject the same instance into a field and into a method on the same target-instance? If you want to have a field variable to cache the value, you can set this from the method.
If you feel this is a bug, please file it here: https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Platform
I would like to inject a buisiness service bean in a sub resource which is defined in a dedicated class and delivered by a sub resource locator.
Some example code:
A root resource
#RequestScoped
#Path("service")
public class MyResource {
#Context
ResourceContext resourceContext;
// Sub resource locator
#Path("subservice")
public MySubResource locateToSubResource () {
// I don't want to create it myself.
return resourceContext.getResource(MySubResource.class);
}
}
The corresponding sub resource
#RequestScoped
public class MySubResource {
// Note that businessBean itself consists of
// multiple ejbs that also need to be injected so that it can do its job!
#Inject
private BusinessBean businessBean;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String get () {
return businessBean.doStuff();
}
}
Jersey won't CDI let invoke the dependencies... Note that the resources are managed objects. Otherwise it wouldn't even be possible to inject a bean in a root resource (here I'm pushing my other questions' view count to get more opinions ;-))!
I tried everything I can think of but it just won't work...
Currently I'm using the libraries that are shipped with glassfish 4.
And of course, thank you in advance (almost forgot that)!
Okay, I figured it out.
It is really kind of stupid. Sometimes you have to roll back completely.
There must have been something wrong with my initial attempt (typo, left out something...I cannot reproduce it, whatever).
I slightly changed the root resource from above:
#RequestScoped
#Path("service")
public class MyResource {
#Inject MySubResource mySubResource;
// Sub resource locator
#Path("subservice")
public MySubResource locateToSubResource () {
return mySubResource;
}
}
Yes, that's it. I must admit, that's the most intuitive solution one can imagine and if such an approach don't work one must have done something wrong... Dont't ask me what exactly was the cause.
I guess it's as always - sleep deprivation let people turn into morons.
I solved like this.
public SubResource subResource() {
return CDI.current().select(SubResource.class).get();
}
I'm trying to add Dagger to an existing web application and am running into a design problem.
Currently our Handlers are created in a dispatcher with something like
registerHandler('/login', new LoginHandler(), HttpMethod.POST)
Inside the login handler we might call a function like
Services.loginService.login('username', 'password');
I want to be able to inject the loginService into the handler, but am having trouble figuring out the best approach. There is a really long list of handlers in the dispatcher, and injecting them all as instance variables seems like a large addition of code.
Is there a solution to this type of problem?
Based on your comment about having different services to inject. I would propose next solution.
ServicesProvider:
#Module(injects = {LoginHandler.class, LogoutHandler.class})
public class ServicesProvider {
#Provides #Singleton public LoginService getLoginService() {
return new LoginService();
}
}
LoginHandler.java:
public class LoginHandler extends Handler {
#Inject LoginService loginService;
}
HttpNetwork.java
public class HttpNetwork extends Network {
private ObjectGraph objectGraph = ObjectGraph.create(new ServicesProvider());
public registerHandler(String path, Handler handler, String methodType) {
getObjectGraph().inject(handler);
}
}
There is one week point in this solution - you can't easily change ServiceProvider for test purpose (or any other kind of purpose). But if you inject it also (for example with another object graph or just through constructor) you can fix this situation.