I require a stateful Web Service and I got it working so far using #HttpSessionScope. The service runs in a Servlet provided by the OSGi HttpService. This servlet is created by some Builder service in my OSGi environment. This builder has some services that need to be injected into my Web Service when it gets instantiated. I know that we have the #Inject and the #Resource annotations for this purpose, but I cannot find a way to add my external object to Glassfish Metro so that those objects get injected into my services.
Have a look to this example:
#HttpSessionScope
#WebService
public class AImpl implements A {
#Inject
private ADelegated delegated;
...
}
How can I declare an object of ADelegated to be injected into this Web Service? Is there some sort of ResourceInjector in Glassfish Metro that allows me to register an object for injection?
Related
If I in my AppHostBase descendant (web api project ) use container.AutoWire(this), it will result in a NullReferenceException in the ServiceStack code, if I am using a web project, thus starting it with the CreateHostBuilder(args).Build().Run(); in the main method.
The error is reproduced in this Github project: https://github.com/tedekeroth/ServiceStackAutoWireTest
The error occurs in AppHostBase.Netcore.Cs, line 158:
If I remove the container.AutoWire(this); in TestAppHost.cs, the error goes away, but then the dependency injection does not work, meaning the Logger in TestAppHostproperty is not assigned:
I am not sure why this happens or what I can do about it. I'd appreciate some input, thanks.
Setup
Visual Studio 2019
Target framework: .NET 5.0 (Console Application)
Project SDK: Microsoft.NET.Sdk.Web
ServiceStack 5.11.0
The IOC AutoWire API attempts to autowire all public property dependencies of an object which is definitely something you should never attempt to do with the AppHost which encapsulates the configuration and behavior of your ServiceStack App where indiscriminatingly overriding every public property is going to leave it in a corrupted state.
Registering your AppHost in the IOC shouldn't be necessary as it's available everywhere via the HostContext.AppHost singleton. It's also a bad idea trying to reference any type defined in your Host Project, (the AppHost being the canonical example) since it creates a circular reference to your Host project in your App logic dependencies which shouldn't have any references back to its Host project, your Host project is supposed to reference all your projects .dll's, configure your App's and all its dependencies, not the other way around.
Should you need access to any Plugins it's recommended to use the GetPlugin<T>() API in your Service for optional plugins or AssertPlugin<T>() for required plugins. If you need to resolve any deps manually you can use TryResolve<T>() API in your Service class. For any of your App's custom config I'd recommend registering them in a custom AppConfig class for your Services to access like any other dependencies.
Otherwise if you really need access to the AppHost you can use the HostContext.AppHost singleton. If you absolutely need to have the AppHost in the IOC, just register it as a normal singleton, i.e. don't try to autowire it:
container.Register<IAppHost>(c => this);
However as mentioned earlier I'd strongly advise against it, have everything your App needs in a custom class (e.g. AppConfig) that is accessed like a normal dependency.
I am new to Simple Injector.
I have a WCF service with a class Testservice implementing a interface ITestService. As per the Simple Injector documentation, in the svc markup I have added the factory attribute as "SimpleInjector.Integration.Wcf.SimpleInjectorServiceHostFactory, SimpleInjector.Integration.Wcf". Also in the AppStart , I have registered the container using the following
container.RegisterWcfServices(Assembly.GetExecutingAssembly()); &
container.Register<ITestService, TestService>(Lifestyle.Scoped);
The WCF works fine. Now I need to consume the service TestService from my MVC app.
In my MVC App, I have added the SimpleInjector.Integration.Web and SimpleInjector.Integration.Web.MVC through Nuget and also added the WCF service reference.
I am struck on registering the TestService class in App Start of my MVC application in order to inject in my controller. The container needs to be registered as
container.Register(ITestService, <TImplementation>);
but I am unable to resolve or find out what I need to give on the TImplementation. It requires a Implementation class which is the TestService but the TestService is available in WCF componebt and only I have the interface reference here in my MVC app.
Can somebody guide whether my approach is right and the solution for above. Thanks in Advance.
You can provide a factory method to SimpleInjector in the register method that it will use to build your object.
container.Register<ITestService, TestService>(Lifestyle.Scoped);
Can be written as
container.Register<ITestService>(() => new TestServiceClient(), Lifestyle.Scoped);
You are then free to choose the constructor you want to use in the factory method
I'm developing a web-service with EJB 3.0 And Spring 3.2,on Weblogic 10.3.5 application Server.
At first,using the default Weblogic JAXWS implementation,
I am able to inject an ejb instance into the #Webservice class with #EJB annotation.
Then I moved from default weblogic JAXWS implementation to METRO STACK (Jaxws 2.3). All seems to work well execpet for EJB dependency injection. Now fooEJB instance is always null.
#Webservice
public class HelloService
{
#EJB
private IFooEJB fooEJB; // Work only with default weblogic JAXWS implementation
}
Is there a way to make #EJB di working with METRO JAXWS 2.3 ?
Thank you
To sum up my failing project: My #ServerEndpoint class is packaged in a WAR together with the beans.xml file. My WAR in turn is packaged in a EAR and this EAR file is what gets deployed to a GlassFish 4 server that internally use Tyrus.
Should it be possible?
The WebSocket specification says:
Websocket endpoints running in the Java EE platform must have full
dependency injection support as described in the CDI specification.
Websocket implementations part of the Java EE platform are required to
support field, method, and constructor injection using the
javax.inject. Inject annotation into all websocket endpoint classes,
as well as the use of interceptors for these classes.
The only thing I can understand of this paragraph is that injecting an Enterprise JavaBean into a WebSocket should be no rocket science. However, for me, whatever I do, it fails to work. I feel that most intuitively one should only need to prefix a server endpoint instance field with the #EJB or #Inject annotation, but no one of these annotations work. The variable will be null.
Already a known problem?
One Internet source says a bit cryptically that "due to a bug" he must use constructor injection. I saw that he had added the annotation #Named to the server endpoint. I used the famous copy paste pattern and did exactly what he did, with and without the #Named annotation, and it still don't work. In fact, my #Inject annotated constructor is never even called!
The Tyrus user guide says that one can mix together anyone of the famous session bean declaration annotations with the server endpoint (#Stateful, #Stateless and #Singleton). So I did, still the injection fails to happen. It doesn't matter if I use the annotation #Inject or #EJB.
And that is strange, because the book Java EE 7 Developer Handbook claims to have a working example on page 27 and page 28 based on the same approach. Author Peter Pilgrim annotates his server endpoint #Stateless. He then uses #Inject to do the injection. He says:
In Java EE 7 we must also declare [our server endpoint] as a stateless
EJB with #Stateless in order to inject [another EJB] as a dependency.
(This is a consequence of Java for WebSocket 1.0 specification.) Note
that we can use #javax.annotation.Inject from CDI.
Okay so he says we must use a #Stateless annotation, and "notes" that one can use #Inject. For me, it sounds utterly strange that we "must" use a #Stateless annotation on a server endpoint which according to the specification, is everything else than stateless (!). I've read elsewhere on the Internet that using #Inject instead of #EJB should be one fix. Peter "notes" that "we can use" #Inject but it smells fishy, as if he never got #EJB to work at all and now tries to flee responsibility.
Well, whatever the reason ("bug" or "consequence of the specification"), I couldn't get my dependency injection to work whatever vivid mix of annotations I used on the endpoint class itself or on the instance field.
The ultimate fix
Is to programmatically use a JNDI lookup, but it looks ugly and should be avoided.
(just restating what I wrote into comment to get this question from "unanswered" list)
You should checkou out Tyrus CDI sample/test.
It demonstrates list what you can do with current implementation. We are always open for new test cases, but there are some issues with the spec itself - standard Request scopes don't work for WebSocket runtime, because it handles messages outside of servlets service/doFilter methods. See WEBSOCKET_SPEC-196 and WEBSOCKET_SPEC-197.
For me. annoting the websocket with #Stateful and EJB object declaration with #EJB did the work.
#Stateful
#ServerEndpoint(value = "/profileregistration")
public class ProfileRegistrationEndpoint {
#EJB
private ProfileRegistration profileRegEJB;
....
}
I have a piece of code that encapsulates functionality that isn't specific to Orchard. However i need to make it available in Orchard via dependency injection. So, I built up an Autofac Module that registers all components (types), but I can't find a way to inform Orchard's Autofac Container about it.
From what i red, there are two ways to add a module to a container:
By supplying the module at to the ContainerBuilder (usually at start-up),
Or by updating the already built Container at runtime with a ContainerBuilder
I can approach the problem in the first way, but I rather do a variant of the second if there is such?
Just add a class deriving from Autofac.Module to your Orchard module and that's it. It will get automatically picked by Orchard during the container construction.
Piotr Szmyd's answer is fundamentally correct, but here's some more detail:
Your Orchard Module is the new .csproj that you've added to the Orchard.sln
Add Autofac as a reference to that csproj (make sure you use the version included with Orchard - not nuget. See here for more details about that problem)
Then add a class that derives from Autofac.Module and which implements Load(ContainerBuilder).
e.g.
using System;
using Autofac;
namespace MyCustom.Module.Namespace
{
public class LoaderModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyClass>().As<IMyInterface>();
}
}
}
As an additional note:
The Autofac registration code only gets invoked at application startup time.
If you are running with the site sitting locally in IIS and the code in VS, then the dynamic compilation nature of Orcahrd means that when you recompile the code, the application doesn't stop.
So in order for this Autofac registration code to be hit (and also for any channges to it to take effect) you have to iisreset to kill the application, so that it reloads the Autofac Registrations.