I want to inject a Singleton EJB into my POJO class.
With the new EJB 3.1 spec, is it possible to inject an EJB into a POJO?
I know in EJB 3.0, the #EJB annotation could be used to inject an EJB, but this did not work on simple POJOs.
#javax.inject.Inject is also not working for me.
One more thing is, what is the difference between a container and a non-container resource?
How do I achieve it, I am using JBoss AS 7.1.1.
EE is designed around the idea of component classes (EJBs, servlets, etc.). An EE container can only perform injection when it controls the creation of the object, which does not apply for POJO, so you cannot use EE injection on POJO objects.
For CDI to work, you need to add META-INF/beans.xml to your archive. Even then, you cannot create the POJO instance using new. You always have to let the container create the instance, so either #Inject the POJO, which can then #Inject the EJB, or use javax.enterprise.inject.spi.BeanManager.
#EJB won't work for you so you have only two options - JNDI lookup or using CDI. Something like
#Inject
private MyEJB ejb;
should work for you. Also check that you have beans.xml in the WEB-INF folder in order to activate CDI container.
And for the difference - it is almost the same (while it's recommended to use #Inject) with only exception - you still have to use #EJB for injecting remote beans.
Reason why you can't use service = new ServiceClass(); is that service object will not be managed by the container - that means that no injections will be peformed after creation of this class because container is no longer in control of this object. Very naively said, if you do
#Inject
ServiceClass service;
container will create new instance, then perform injections and return it to you.
Related
According to the official documentation here:
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#authorization-filters
To implement a custom ActionFilter in ASP.NET Core I have three choices:
SeviceFilterAttribute
TypeFilterAttribute
IFilterFactory
But for all three it is stated that:
Shouldn't be used with a filter that depends on services with a lifetime other than singleton.
So how can I inject scoped services in my custom ActionFilter? I can easily get a scoped service from the current HttpContext like this:
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
ISubscriptionHelper subscriptionHelper =
actionContext.HttpContext.RequestServices
.GetRequiredService<ISubscriptionHelper>();
}
But then I am wondering if I am doing something wrong? What is the correct way to depend on scoped services in a custom ActionFilterAttribute?
Resolving services from the HttpContext.RequestServices will correctly resolve scoped and transient instances without causing any problems such as Captive Dependencies. In case resolved components implement IDisposable, they will be disposed of when the request ends. ASP.NET Core passes on the current HttpContext object to filter's OnActionExecuting method and that HttpContext gives access to the DI Container.
This is completely different from injecting those services into the constructor, because the action filter will be cached for the lifetime of the application. Any dependencies stored in private fields will, therefore, live as long as that filter. This leads to the so called Captive Dependency problem.
Code that accesses the DI Container (the HttpContext.RequestServices is your gateway into the DI Container) should be centralized in the infrastructure code of the startup path of the application—the so called Composition Root. Accessing your DI Container outside the Composition Root inevitably leads to the Service Locator anti-pattern—this should not be taken lightly.
To prevent this, it is advised to keep the amount of code inside the action filter as small as possible and implement the filter as a Humble Object. This means that preferably, the only line of code inside the filter is the following:
actionContext.HttpContext.RequestServices
.GetRequiredService<ISomeService>() // resolve service
.DoSomeOperation(); // delegate work to service
This means all (application) logic is moved to the ISomeService implementation, allowing the action filter to become a Humble Object.
I've been using asp.net core dependency injection and I have seen an not expected behavior, at least for me. I'm adding a new service to the container like this:
services.AddScoped<IMyClass>(provider =>
{
return new MyClass(
"anyValue"
});
After that, I inject the class into another class to use it:
public class AnotherClass(IMyClass xxx){
}
The thing is that there are a couple configurations that are made on the MyClass constructor based on request information. The problem is that I've seen the MyClass constructor be executed at the application startup only. After that, the class seems to use the same instance for all calls. As I'm using Scoped service I'm expecting to have a new instance for each request, am I wrong?
Thanks.
Ok. The problem was that the class that was receiving the injection was added to the container as singleton. I just changed it to Scoped and everything worked well.
Thanks!
In my WCF project I register my interface using Castle Windsor in the global.asax:
Component.For<IStrategy>()
.ImplementedBy<MyStrategy>()
.LifestylePerWcfOperation(),
Then later on in the same file I configure NHibernate using FluentNhibernate using a provider:
FluentConfiguration configuration = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.ConnectionString(myConnString)
.Provider<ConnectionProvider>())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<TenantMap>()) etc etc
However this ConnectionProvider is hosted in a common shared dll library as there are other WCF services that need to use it. I want to register this dependency as below but it doesn't work which means I have to manually new up a instance.
public ConnectionProvider()
{
// doesnt work
using (IDependencyScope scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope())
{
_myStrategy = scope.GetService<IStrategy>();
}
}
Is there anyway to make this work? Its like its lost scope as its in another assembly now. In the same assembly the DependencyScope works fine and creates an instance, but I want to keep it in a shared dll.
EDIT: The error I get is "System.Web.Http.Dependencies.EmptyResolver" on a watch on this bit of code: GlobalConfiguration.Configuration.DependencyResolver
I can see several problems with the code above:
1) You are registering IStrategy,MyStrategy with a per WcfOperation lifestyle. This means that windsor will create a strategy for each WcfOperation. On the otherhand you are trying to manually set the lifestyle of the component by using scope.GetService. For scope.GetService to work you will need a lifestyle scoped.
2) Assuming that the code for ConnectionProvider above is the constructor, it seems that the constructor is trying to get something from the container. This is in general a bad idea, and even worse when using an Ioc container like windsor. Instead pass the IStrategy to the constructor (inject it).
3) Seeing that you are calling the container a constructor here, probably means that you are not adhering to the principle that there should be only 3 calls to the container, 1 to register component, 1 to retrieve a top level component, and 1 to release the container.
I suggest you read a bit more about depedency injection and Ioc containers in general to fully understand how to work with this container.
I have CDI RequestScoped bean and much more java class that are not beans. in any of these java classes, I want to use my bean but it can be injected (why? I do not know) one possible way is using this code :
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
EntityManagment em = (EntityManagment) context.lookup("java:app/drools-guvnor/EntityManagment");
that work well if my bean is stateless and localbean. what I can do for none stateless and localbeans?
There is no JNDI-Name for CDI given.
You could either register them yourself or you create an EJB that has been injected with your object. Then you can lookup this EJB and get your injected object from there.
I'm trying to hock up WCF with dependency injection. All the examples that I have found is based on the assumptions that you either uses a .svc (ServiceHostFactory) service or uses app.config to configure the container. Other examples is also based on that the container is passed around to the classes.
I would like a solution where the container is not passed around (not tightly coupled to Unity). Where I don't uses a config file to configure the container and where I use self-hosted services.
The problem is - as I see it - that the ServiceHost is taking the type of the service implementation as a parameter so what different does it do to use the InstanceProvider?
The solution I have come up with at the moment is to register the ServiceHost (or a specialization) an register a Type with a name ( e.g. container.RegisterInstance<Type>("ServiceName", typeof(Service);).
And then container.RegisterType<UnityServiceHost>(new InjectionConstructor(new ResolvedParameter<Type>("ServiceName"))); to register the ServiceHost.
Any better solutions out there? I'm I perhaps way of in my assumptions.
Best regards,
Michael
Use Constructor Injection to wire up your service implementation, just like you would with any other class.
Here's a writeup on how to make WCF understand Constructor Injection.
The example in that answer demonstrates Poor Man's Injection, but you can extrapolate from it and set up your UnityContainer instance in the ServiceHostFactory instead of a hard-coded dependency.
You pass the container instance all the way to the custom IInstanceProvider. Now you can use the container in the GetInstance method:
public object GetInstance(InstanceContext instanceContext)
{
var serviceType = instanceContext.Host.Description.ServiceType;
return this.container.Resolve(serviceType);
}