Ninject: What happens to non-disposable InRequestScope and InTransientScope objects after the HTTP request is finished? - ninject

I have searched a lot about these question, here and a lot of other places, but not getting everything I want to know!
From a WebApi project point-of-view, when are InTransientScope objects Created? In the Ninject docs it is stated that such objects are created whenever requested, but in a web api project that handles HTTP requests, the instance is created at the request start time so in this regard it is the same as InRequestScope then?
In a WebApi project, is it okay to use InTransientScope objects knowing that they will never be kept track of by Ninject? If Ninject never keeps track of Transient objects, then what is the purpose of this scope and what happens to such objects after they have been used?
If I declare an object with InRequestScope and that object doesn't implement the IDisposable interface, what happens to such object after the web request has completed? Will it be treated the same way as an InTransientScope object?
Are different scopes to be used for: WebApi controllers, Repositories(that use a InRequestScope Session that is created separately) and Application services?

There's two purposes for scopes:
Only allow one object to be created per scope
(optionally) dispose of the object once the scope ends.
As said, the disposal is optional. If it doesn't implement the IDisposable interface it's not being disposed. There's plenty of usecases for that.
The InTransientScope is the default scope - the one being used if you don't specify another one. It means that every time a type A is requested from the kernel one activation takes place and the result is returned. The activation logic is specified by the binding part that follows immediately after the Bind part (To<...>, ToMethod(...),...).
However, this is not necessarily at the time the web-request starts and the controller is instanciated. For example, you can use factories or service location (p.Ex. ResolutionRoot.Get<Foo>()) to create more objects after the controller has been created. To answer your questions in short:
When: When a request takes place or whenever your code asks for a type from Ninject either directly (IResolutionRoot.Get(..)) or through a factory. As InTransientScope objects are not being tracked they will not be disposed, however, if they are not disposable and the entire request code requests only one IFoo then practically there's is no discernible difference (apart from the slight performance hit due totracking InRequestScope()-ed objects)
As long as you don't need to make sure that instances are shared and/or disposed this is completely fine. After they are not being used anymore, they will get garbage-collected like any object you would new yourself.
When the scope ends ninject will remove the weak reference to the non-IDisposable object. The object itself will not be touched - just like when bound InTransientScope()
That depends on your specific requirements and implementation details. Generally one needs to make sure that long-scoped objects don't depend on short-scoped objects. For example, a Singleton-Service should not depend on a Request-scoped object. As a baserule, everything should be InTransientScope() unless there's a specific reason why it should not be. The reason will dictate what scope to use...

Related

Ninject provider can't resolve types registered within a named scope

I am using the NamedScoped Ninject extension in an attempt to create object graphs that are constructed everytime a command handler is constructed by the container. In other words, I want a fresh object graph for every command that might get processed by its corresponding handler.
I have used the .DefinesNamedScope("TopLevelOrhcestrator") binding when registering my "command handlers" as they are the top level for command processing.
A type in this named scope needs to be injected with the result of a method call on a type already registered in this named scope. I thought the best way to do this would be with a ninject provider.
Inside the provider I attempt to resolve the type in hopes I can call a method on it to pass into another object I am creating within this named scope. The problem I'm having is that when I ask the IContext for the instance inside the customer provider I get an exception that says "No matching scopes are available, and the type is declared InNamedScope(TopLevelOrchestrator).
context.Kernel.Get<TypeAlreadyRegisteredInScope>().MethodThatGetsAnotherDependency()
Is it possible to get types from the container inside a Ninject provider when they are registered inside a named scope?
EDIT
I apologize if the use case seems a bit odd, I am experimenting with some ideas about how to manage my units of work and other services/managers that may need a handle to the uow to complete a business usecase. I know its common for the unit of work to be "started" and then passed into all dependencies that may need to take part in a larger process. I was thinking I'd rather let my orchestrator take a unit of work factory so that it could deterministically destroy the UOW and it would be clear who the owner of a usecase is. What would get supplied to the managers/services would be a proxy to the unit of work that would be null until a real unit of work was started by the orchestrator. That's why I was attempting to link the proxy from the already registered type in my provider. This is all very experimental at this point and was testing some ideas.
I'd be happy to hear any further thoughts.
For MethodThatGetsAnotherDependency() to be able to .Get<>() an instance that is bound .InNamedScope(...) you will need to add the Context Preservation Extension.
This is because NamedScope is adding a parameter to the request context of the binding that has .DefinesNamedScope(...). As soon as that request is over, that context and it's parameters are forgotten. Now with the ContextPreservation extension the context is kept and reused for late / factory creations (Func<>, interface factory with .ToFactory() binding...). It think it should also work with providers.
If not, just switch to a factory instead of a provider.
However i have to admit that i don't fully understand why/what you are trying to achieve. There might be simpler ways.

Unable to access the service instance from within an implementation of IDataContractSurrogate

this is my first post, and I really have tried hard to find an answer, but am drawing a blank thus far.
My implementation of IDataContractSurrogate creates surrogates for certain 'cached' objects which I maintain (this works fine). What doesn't work is that in order for this system to operate effectively, it needs to access the service instance for some properties of the instance which it is maintaining from the interaction with its client. Also, when my implementation of IDataContractSurrogate works in its 'client mode' it needs access to the properties of the client instance in a similar way. Access to the information from the client and service instance affects how I create my surrogate types (or rather SHOULD do if I can answer this question!)
My service instancing is PerSession and concurrent.
On the server side, calls to GetDataContractType and GetDeserializedObject contain a valid OperationContext.Current from which I can of course retreive the service instance. However on the client side, none of the calls yield an OperationContext.Current. We are still in an operation as I am translating the surrogate types to the data contract types after they have been sent from the server as part of its response to the client request so I would have expected one? Maybe the entire idea of using OperationContext.Current from outside of an Operation invocation is wrong?
So, moving on, and trying to fix this problem I have examined the clientRuntime/dispatchRuntime object which is available when applying my customer behaviour, however that doesn't appear to give me any form of access to the client instance, unless I have a message reference perhaps... and then calling InstanceProvider. However I don't have the message.
Another idea I had was to use IInstanceProvider myself and then maybe build up a dictionary of all the ones which are dished out... but that's no good because I don't appear to have access to any session related piece of information from within my implementation of IDataContractSurrogate to use as a dictionary key.
I had originally implemented my own serializer but thats not what I want. I'm happy with the built in serializer, and changing the objects to special surrogates is exactly what I need to do, with the added bonus that every child property comes in for inspection.
I have also looked at applying a service behavior, but that also does not appear to yield a service instance, and also does not let me set a Surrogate implementation property.
I simply do not know how to gain access to the current session/instance from within my implementation IDataContractSurrogate. Any help would be greatly appreciated.
Many thanks,
Sean
I have solved my problem. The short answer is that I implemented IClientMessageFormatter and IDispatchMessageFormatter to accomplish what I needed. Inside SerializeReply I could always access the ServiceInstance as OperationContext.Current is valid. It was more work as I had to implement my own serialization and deserialization, but works flawlessly. The only issue remaining would be that there is no way to get the client proxy which is processing the response, but so far that is not a show stopper for me.

Transient vs per webrequest lifestyle, what constitutes a web request?

What are the differences between these two life cycles?
Let's say my MVC controller is being supplied with an object that was configured as transient, then when someone visits a method in that controller a new instance is injected in the class constructor and then the method is called.
Each and every get/post to the controller is a new request, right? If so, then I don't see any difference between the two.
Can someone explain / provide an example of when you would use one vs the other?
The difference between Transient and Web Request is negligible when registering your Controller types as Transient, since -as you said- each request gets its own Controller and only one controller instance for that type is resolved in that request.
Things start to get interesting when there's a dependency in the Controller's object graph that is refered by multiple components. A good example for when this might happen is with a Unit of Work (such as Entity Framework's DbContext). Multiple services inside the object graph might need that same Unit of Work, and for the correctness of your application they all need the same instance during that request; but each request must get a new Unit of Work instance.
To learn more about when and when not to have one Unit of Work Per Request or not, read this:
One DbContext per web request… why?
You cannot fault your DI tool for failing to distinguish between cases it doesn't know. PerWebRequest scope is a scope that lasts from the beginnning of a webcall to the end of the webcall. Transient lives as long as you hold a reference to the resolved entity (usually the caller's lifetime).
Of course if the resolving entity has the same lifespan as the request you won't see any difference. A PerWebRequest lifespan lives from the beginning of a request to its end. A Transient lifespan lives according to reference held on it; if you need some logging completely dependent on the current webrequest you would set a PerWebRequest lifespan. The controller that handles the request would get a Transient lifespan since its work finished it wouldn't be needed anymore

Context and Instance in WCF

I am reading Juval Löwy's Programming WCF Sevices. It mentions:
In WCF, we have Context in which we have the instance. By default, the lifetime of the context is the same as that of the instance it hosts. We can have separate lifetimes for both.
WCF also allows a context to exist without an associated instance at all.
Why would we release the instance and keep the context empty?
Coincidentally I recently read the chapter you're probably referring to. In his book Löwy explains why this may be useful. First he writes:
WCF also allows a context to exist without an associated instance at all. I call this instance management technique context deactivation.
After mentioning this is typically done using an OperationBehavior with a specific ReleaseInstanceMode, he goes on and hints on when you could use this:
You typically apply instance deactivation on some but not all service methods, or with different values on different methods. [...] The reason you typically apply it sporadically is that if you were to apply it uniformly, you would end up with a per-call-like service, in which case you might as well have configured the service as per-call.
So you can use this "deactivation" to ensure only certain methods in a service with sessions behave as if they were part of a per-call service. The abovementioned MSDN article also explains this, in a different wording:
Use the ReleaseInstanceMode property to specify when WCF recycles a service object in the course of executing a method. The default behavior is to recycle a service object according to the InstanceContextMode value. Setting the ReleaseInstanceMode property changes that default behavior. In transaction scenarios, the ReleaseInstanceMode property is often used to ensure that old data associated with the service object is cleaned up prior to processing a method call.
Disconnecting the context from the instance makes sense when:
Instance creation is customized/extended. For example if you are creating your service instance with a custom IInstanceProvider with a dependency injection library (for example Unity) you might want a Unity lifetime manager to handle the service instance lifetime.
Some but not all operations result in an expensive service instance to be invalidated. For example: The service object loads a large expense resource as a part of creation. If the service operations called by the client modify or invalidate the resource, it needs to be disposed and reloaded for the next caller. If the operations don’t invalidate the resource the service instance can be reused by the next caller. (In almost all cases there’s a better way to solve this problem, but WCF allows it).
I’m sure there are additional use cases.

Passing client context using Unity in WCF service application

I have a WCF service application (actually, it uses WCF Web API preview 5) that intercepts each request and extracts several header values passed from the client. The idea is that the 'interceptor' will extract these values and setup a ClientContext object that is then globally available within the application for the duration of the request. The server is stateless, so the context is per-call.
My problem is that the application uses IoC (Unity) for dependency injection so there is no use of singleton's, etc. Any class that needs to use the context receives it via DI.
So, how do I 'dynamically' create a new context object for each request and make sure that it is used by the container for the duration of that request? I also need to be sure that it is completely thread-safe in that each request is truly using the correct instance.
UPDATE
So I realize as I look into the suggestions below that part of my problem is encapsulation. The idea is that the interface used for the context (IClientContext) contains only read-only properties so that the rest of the application code doesn't have the ability to make changes. (And in a team development environment, if the code allows it, someone will inevitably do it.)
As a result, in my message handler that intercepts the request, I can get an instance of the type implementing the interface from the container but I can't make use of it. I still want to only expose a read-only interface to all other code but need a way to set the property values. Any ideas?
I'm considering implementing two interfaces, one that provides read-only access and one that allows me to initialize the instance. Or casting the resolved object to a type that allows me to set the values. Unfortunately, this isn't fool-proof either but unless someone has a better idea, it might be the best I can do.
Read Andrew Oakley's Blog on WCF specific lifetime managers. He creates a UnityOperationContextLifetimeManager:
we came up with the idea to build a Unity lifetime manager tied to
WCF's OperationContext. That way, our container objects would live
only for the lifetime of the request...
Configure your context class with that lifetime manager and then just resolve it. It should give you an "operation singleton".
Sounds like you need a Unity LifetimeManager. See this SO question or this MSDN article.