MIcronaut-Jaxrs #RequestScope create only one object even with multiple requests - jax-rs

I am trying to inject a io.micronaut.runtime.http.scope.RequestScope object into my jaxrs resource. Here I am priting object to see if it creates different objects for each request. But the object created Only once, even when I sent multiple requests.
Is this a known issue ? Any other way to work around this if that's the case.
#RequestScope
public class RequestScopeObjectX {
public RequestScopeObjectX() {
System.out.println("-------------------------"+this);
}
}
And in. my jaxrs resource class I am doing injecting it
#Inject
RequestScopeObjectX objectX;

Related

Controlling lifetime of objects created by factory generated by ToFactory()

I am using the following Ninject related nuget packages in an MVC 5 WebAPI application:
Ninject.MVC5
Ninject.Extensions.Factory
ninject.extensions.conventions
I have a simple repository and a corresponding factory class like so:
public interface ITaskRunner
{
void Run();
}
public interface IRepository<T> where T: class
{
T[] GetAll();
}
public interface IRepositoryFactory<T> where T: class
{
IRepository<T> CreateRepository();
}
I have setup the Ninject bindings using ToFactory() from Ninject.Extensions.Factory like so:
kernel.Bind<ITaskRunner>().To<TaskRunner>().InSingletonScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
kernel.Bind<IRepositoryFactory<Contact>>().ToFactory();
I am using the factory in the following class:
public class TaskRunner : ITaskRunner
{
//MyTask is a simple POCO class(not shown for brevity)
IRepositoryFactory<MyTask> repoFactory = null;
IRepository<MyTask> repo = null;
public TaskRunner(IRepositoryFactory<MyTask> repoFactory)
{
this.repoFactory = repoFactory;
repo = repoFactory.CreateRepository();
}
//implementation elided
}
I am noticing that the call to repoFactory.CreateRepository() always returns the same instance of the factory (dynamic proxy) that Ninject generates.
Question : Is there a way to change/control this behavior and set a "lifetime" such as Transient, PerThread etc. for the instance that "CreateRepository" returns?
In this particular case, tasks might be processed asynchronously on multiple threads and the repository is not thread safe and hence singleton behavior for the instance returned from "CreateRepository" is not desirable.
I'm not sure what you are trying to achieve, but results you are seeing are quite expected because your TaskRunner is bound as Singleton (so constructed once), and you retrieve your repository in the TaskRunner constructor, which again happens once, and so repo is always the same instance. Note this happens regardless of how you bind IRepository and IRepositoryFactory, see Captive Dependency post by Mark Seemann for details http://blog.ploeh.dk/2014/06/02/captive-dependency/.
In fact, if you need to create repo in the constructor, you could just inject IRepository itself. The power of the Factory extension lies in the fact that it allows to resolve instances at runtime, not construction time. For example, if your TaskRunner has Run() method, you can create repository in it, so each task to run can have its own instance.

Update #ViewScoped bean from JAX-RS service

I've got a mishmash of JAX-RS webservices and JSF/CDI beans. Usual display of my #Entitys is from a #ViewScoped JSF bean collecting relevant entities in a #PostConstruct method:
#Named #ViewScoped
public class Manager {
private List<MyEntity> entities; // + getter
private MyEntity instance; // + getter/setter
#PostConstruct
public void init() {
entities = collectEntities();
instance = new MyEntity();
}
public void save() {
instance = persistInstance();
entities.add(instance);
}
// additional methods like collectEntities, persistInstance
}
Normal operation can call manager.save to persist a new entity and display it alongside the old ones.
Now, a JAX-RS service can also create entities that should be in the collection managed by such a scoped bean:
#Path("/myentity")
public class MyEntityService {
#PersistenceContext EntityManager em;
#PUT
public Response save(#FormParam("name") String name) {
MyEntity entity = new MyEntity(name);
em.persist(entity);
return Response.ok(entity.getId()).build();
}
}
The service can be called on a page where there's also a manager instance.
My question is: how can I make the existing manager instance aware of the additional entity, so that a JSF ajax re-render of a manager.entities list will include the entity created by the webservice?
So far, I've tried a CDI event observed by the CDI bean. The event gets fired from the service but is never received by the bean.
As a workaround I can fire a JSF ajax function telling the manager to refresh it's entity list (leveraging <a4j:jsFunction action="#{manager.init()}">, for example). However I'm unsure about the implications: will this expose a timing problem when the user asks for the entity list to be displayed earlier than the initialization can complete (the list isn't shown by default)?
As a total hack I can probably grab the bean from the session in the service and punch my data in. I shudder just thinking about it.
View scope is something that is JSF specific, as a JSF specific CDI context. It is alive only within the scope of the given view. JAX-RS has no specific way that I can think of to access this scope. I don't believe view scope would even have access to the HTTP request.

HttpContextBase.Request exception when using Ninject MVC3

I have a service that takes a dependency on HttpContextBase.
Ninject is injecting this for me already as it's set up in the MvcModule to return new HttpContextWrapper(HttpContext.Current) when HttpContextBase is requested
I want to use this service in Application_AuthenticateRequest, so i'm using property injection so that Ninject resolves it for me
When I try and access Request.UserHostAddress on the HttpContextBase I get a Value does not fall within the expected range exception
If I call HttpContext.Current.Request.UserHostAddress directly it works without problems
ExampleService.cs
public class ExampleService : IExampleService {
HttpContextBase _contextBase;
public ExampleService(HttpContextBase contextBase) {
_contextBase = contextBase;
}
public void DoSomething() {
var ip = HttpContext.Current.Request.UserHostAddress; <== this works
ip = _contextBase.Request.UserHostAddress; <== this fails
}
}
Global.asax
[Inject]
public IExampleService ExampleService { get; set; }
public void Application_AuthenticateRequest() {
ExampleService.DoSomething();
}
I'm missing something here, but I can't see what
Dependencies that are injected into classes live as long as the the class they get injected into, because the class holds a reference to them. This means that in general you should prevent injecting dependencies that are configured with a lifetime that is shorter than the containing class, since otherwise their lifetime is 'promoted' which can cause all sorts of (often hard to track) bugs.
In the case of an ASP.NET application, there is always just one HttpApplication instance that lives as long as the AppDomain lives. So what happens here is that the injected ExampleService gets promoted to one-per-appdomain (or singleton) and since the ExampleService sticks around, so does its dependency, the HttpContextBase.
The problem here of course is that an HTTP context -per definition- can't outlive a HTTP request. So you're storing a single HttpContextBase once, but it gets reused for all other requests. Fortunately ASP.NET throws an exception, otherwise you would probably be in much more trouble. Unfortunately the exception isn't very expressive. They could have done better in this case.
The solution is to not inject dependencies in your HttpApplication / MvcApplication. Ever! Although it's fine to do so when you're injecting singletons that only depend on singletons recursively, it is easy to do this wrong, and there's no verification mechanism in Ninject that signals you about this error.
Instead, always resolve IExampleService on each call to AuthenticateRequest. This ensures that you get an ExampleService with the right lifetime (hopefully configured as per-web-request or shorter) and prevents this kind of error. You can either call into the DependencyResolver class to fetch an IExampleService or call directly into the Ninject Kernel. Calling into the Kernel is fine, since the Application_AuthenticateRequest can be considered part of the Composition Root:
public void Application_AuthenticateRequest() {
var service = DependencyResolver.Current.GetService<IExampleService>();
service.DoSomething();
}

WCF Ria DomainService - Initialize WebService on StartUp

Currently, my DomainService does perform an Initialization of a resource everytime a client is connecting to him. Every client should access the same instance of this resource.
I would like to initialize this resource on the StartUp of the WebService. Is there any chance to do that with WCF Ria Services?
EDIT:
Okay, don't mention it. I wanted to use this for an global DbContext object. This isn't a good idea anyway, because there will be multiple threads managed by the HttpApplication which would access the DbContext simultaneously. I will change my implementation to an "per Thread", respectively "per HttpContext", approach. Thanks anyhow.
You can define a class that contains a static property for that resource. In the DomainService you can then access that property. It would then be initialized only when it is accessed the first time.
Example:
public class ResManager {
public static MyObject {...}
}
In the DomainService:
public IQueryable<SomeClass> GetSomeObjects()
{
// you can access it here and it will not be initialized
// every time the DomainService is called
MyObject obj = ResManager.MyObject;
return new List<SomeClass>().AsQueryable();
}
If you want to initialize it when the Service is started, then you should be able to do that in the Global class.

WCF - Return object without serializing?

One of my WCF functions returns an object that has a member variable of a type from another library that is beyond my control. I cannot decorate that library's classes. In fact, I cannot even use DataContractSurrogate because the library's classes have private member variables that are essential to operation (i.e. if I return the object without those private member variables, the public properties throw exceptions).
If I say that interoperability for this particular method is not needed (at least until the owners of this library can revise to make their objects serializable), is it possible for me to use WCF to return this object such that it can at least be consumed by a .NET client?
How do I go about doing that?
Update: I am adding pseudo code below...
// My code, I have control
[DataContract]
public class MyObject
{
private TheirObject theirObject;
[DataMember]
public int SomeNumber
{
get { return theirObject.SomeNumber; } // public property exposed
private set { }
}
}
// Their code, I have no control
public class TheirObject
{
private TheirOtherObject theirOtherObject;
public int SomeNumber
{
get { return theirOtherObject.SomeOtherProperty; }
set { // ... }
}
}
I've tried adding DataMember to my instance of their object, making it public, using a DataContractSurrogate, and even manually streaming the object. In all cases, I get some error that eventually leads back to their object not being explicitly serializable.
Sure, write a wrapper class that has all of the same public properties available and simply put "get { return internalObject.ThisProperty; }. Decorate the wrapper class so that it works with WCF.
Another option is to write a Proxy class which mirrors the properties of the type you wish to use exactly, and return that via WCF.
You can use AutoMapper to populate the proxy object.
This approach has the advantage that your service's consumers don't need to take a dependency on the third party library in trying to use it.