I have recently tried out Ninject with the Ninject.Web.Mvc extension, and I've noticed something peculiar and, while not breaking, confusing.
In the NinjectHttpApplication abstract class, there is a constructor defined as follows..
/// <summary>
/// Initializes a new instance of the <see cref="NinjectHttpApplication"/> class.
/// </summary>
protected NinjectHttpApplication()
{
this.onePerRequestModule = new OnePerRequestModule();
this.onePerRequestModule.Init(this);
}
I have placed a debugger breakpoint here, and this gets called a few times. I cannot find any real documentation on it. In the implementation code, there is this line that catches my eye.
if (kernel.Settings.Get("ReleaseScopeAtRequestEnd", true))
{
OnePerRequestModule.StartManaging(kernel);
}
My questions are as follows...
What is OnePerRequestModule
Why is this constructor being called multiple times?
What is the purpose of this StartManaging method, if the constructor is called multiple times?
The OnePerRequestModule removes InRequestScope()d objects from the Kernel's Cache upon completion of each HTTP Request.
The NinjectHttpApplication ctor is called multiple time because IIS creates several of them. One NinjectHttpApplication can only handle one request at a time. So IIS generates (at least) one instance per thread.
StartManaging tells all OnePerRequestModules that they shall release the InRequestScoped objects from the specified Kernel after the Request has Ended.
Related
For my application I need to fetch some data asynchronously and do some initialization for each page. Unfortunately, a constructor does not allow me to make asynchronous calls. I followed this article and put all of my code into the OnAppearing method. However, since then I ran into multiple issues since each platform handles the event a little bit differently. For example, I have pages where you can take pictures, on iOS the OnAppearing is called again every time after the camera is closed while Android doesn't. It doesn't seem like a reliable method for my needs, which is also described here:
Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.
I am searching for a method/way where I can perform my own initialization. The constructor would be perfect for that but I cannot perform anything asynchronously in there. Please do not provide me with any work arounds, I am searching for a solution that is the "recommended" way or maybe someone with a lot of experience can tell me what they are doing. (I also don't want to .Wait() or .Result as it will lock my app)
You can use Stephen Cleary's excellent NotifyTaskCompletion class.
You can read more how it works and what to do/don't in these cases in Microsoft's excellent Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding. The highlights of this topics are:
Let’s walk through the core method
NotifyTaskCompletion.WatchTaskAsync. This method takes a task
representing the asynchronous operation, and (asynchronously) waits
for it to complete. Note that the await does not use
ConfigureAwait(false); I want to return to the UI context before
raising the PropertyChanged notifications. This method violates a
common coding guideline here: It has an empty general catch clause. In
this case, though, that’s exactly what I want. I don’t want to
propagate exceptions directly back to the main UI loop; I want to
capture any exceptions and set properties so that the error handling
is done via data binding. When the task completes, the type raises
PropertyChanged notifications for all the appropriate properties.
A sample usage of it:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
Here, the demo is about binding the returned asynchronous value to some bindable property, but of course you can you is without any return value (for simple data loading).
This may be too simple to say, but you CAN run asynchronous tasks in the constructor. Just wrap it in an anonymous Task.
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
Be careful when doing this though as you can get into resource conflict issues if you accidentally open the page twice.
Another thing I like to do is use an _isInit flag, which indicates a first time use, and then never again.
I'm using ASP.NET MVC CORE. I have implemented my own ViewLocationExpander so that I can structure my project the way I want and place my views where I like.
This is accomplished by implementing a class that inherits from IViewLocationExpander and most of the work occurs in the following method:
ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
Everything is working pretty sweet but the interface defines a 2nd method that I don't know how to properly implement:
PopulateValues(ViewLocationExpanderContext context)
I've read articles all over the internet about this interface but no one has really provided much info on what exactly this method is for other than saying vague things about how it helps with caching.
I'd really appreciate it if someone could explain how this method is used by the framework and how I can use it appropriately to aid caching if that is indeed what it is for.
Maybe the following additional info taken directly from a GitHub MVC issue can answer your question:
Caching includes the Values dictionary in its lookup. Unless the PopulateValues() method adds distinct information to ViewLocationExpanderContext.Values, the ExpandViewLocations() method will be called just once per original file name i.e. the initial information is cached from then on.
On top of that, the particular example posed by OP can help understand even better, at least that's what happened to me:
His project has views with the same name under two different directory
trees (say Foo and Bar)
Depending on some data extracted by current action context, the view to locate should be under either one of those trees
Without any code in PopulateValues(), view engine will ask once to locate the view, then use view "standard" data (e.g. ControllerName, ActionName, Area, etc.) in order to cache the actual location where view is found.
So, in OP case, once a view location is cached (say e.g. from Foo directory tree) everytime a view with same name is needed it will always be from that tree, there'll be no way to detect if the one in the other Bar tree should have been actually picked up.
The only way for OP is to customize PopulateValues() by adding specific, distinctive view details to Values dictionary: in current scenario, those are the info extracted from current action context.
That additional info are used two-fold: ExpandViewLocations() might use them when invoked in order to determine proper location, while view engine will use them to cache view location once found.
Dec. 2021 update
Official doc page is more descriptive. From Remarks section:
Individual IViewLocationExpanders are invoked in two steps:
(1) PopulateValues(ViewLocationExpanderContext) is invoked and each expander adds values that it would later consume as part of ExpandViewLocations(ViewLocationExpanderContext, IEnumerable<String>). The populated values are used to determine a cache key - if all values are identical to the last time PopulateValues(ViewLocationExpanderContext) was invoked, the cached result is used as the view location.
(2) If no result was found in the cache or if a view was not found at the cached location, ExpandViewLocations(ViewLocationExpanderContext, IEnumerable<String>) is invoked to determine all potential paths for a view.
Haven't messed around with it enough to be able to give you a concrete answer, but have a look at IViewLocationExpander.PopulateValues(ViewLocationExpanderContext context) on the ASP.NET MVC GitHub repo:
public interface IViewLocationExpander
{
/// <summary>
/// Invoked by a <see cref="RazorViewEngine"/> to determine the values that would be consumed by this instance
/// of <see cref="IViewLocationExpander"/>. The calculated values are used to determine if the view location
/// has changed since the last time it was located.
/// </summary>
/// <param name="context">The <see cref="ViewLocationExpanderContext"/> for the current view location
/// expansion operation.</param>
void PopulateValues(ViewLocationExpanderContext context);
// ...other method declarations omitted for brevity
}
Readability format:
"Invoked by a RazorViewEngine to determine the values that would be consumed by this instance of IViewLocationExpander. The calculated values are used to determine if the view location has changed since the last time it was located.
Parameters:
context: The ViewLocationExpanderContext for the current view location expansion operation."
I've had a look at some classes which implement this interface - some declare the method but leave it empty, others implement it.
NonMainPageViewLocationExpander.cs:
public void PopulateValues(ViewLocationExpanderContext context)
{
}
LanguageViewLocationExpander.cs:
private const string ValueKey = "language";
public void PopulateValues(ViewLocationExpanderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
// Using CurrentUICulture so it loads the locale specific resources for the views.
#if NET451
context.Values[ValueKey] = Thread.CurrentThread.CurrentUICulture.Name;
#else
context.Values[ValueKey] = CultureInfo.CurrentUICulture.Name;
#endif
}
The article "View Location Expander in ASP.NET Core and MVC 6" provides an example. Here's an excerpt of the explanation:
You can add as many view location expanders as you want. IViewLocationExpander interface has 2 methods, PopulateValues and ExpandViewLocations. PopulateValues method allows you to add values that can be later consumed by ExpandViewLocations method. The values you put in PopulateValues method will be used to find cache key. ExpandViewLocations method will be only invoked if there is no cache result for the cache key or when framework is unable to find the view at the cached result. In the ExpandViewLocations method, you can return your dynamic view locations. Now you can register this view location expander in Startup.cs file,
services.Configure<RazorViewEngineOptions>(options =>
{
options.ViewLocationExpanders.Add(new MyViewLocationExpander());
});
Basically the method can populate values into context.Values that will later be used to determine if a cached list should be used or if the ExpandViewLocations will be called....
I've come across this code:
public class ServiceLauncher2 : ServiceBase, IDisposable
And then this:
/// <summary>
/// Disposes the controllers
/// </summary>
// This is declared new as opposed to override because the base class has to be able to
// call its own Dispose(bool) method and not this one. We could just as easily name
// this method something different, but keeping it Dispose is just as valid.
public new void Dispose()
{
foreach (var mgr in _threadManagers)
mgr.Dispose();
base.Dispose();
}
I've never seen this in a Windows Service implementation before. Usually just OnStop/OnStart is overridden. Is this bad practice?
Let's count the ways this is bad practice:
The new keyword is grating, it tells the compiler to shut up about a potential problem in the code. A real one, the code that uses this class can easily end up calling ServiceBase.Dispose() instead. ServiceBase implements the disposable pattern, the correct way to do it is to override the protected Dispose(bool) method
The Dispose() method leaves a _threadManagers collection object behind that contains nothing but dead objects. Which makes the collection dead as a doornail as well, iterating it afterwards is meaningless. It should have been emptied
The only time this Dispose() method can be called is at service termination. Can't do it in OnStop(), it also disposed the ServiceBase. Disposing "controllers" a microsecond before the finalizers run and the process terminates makes no sense. Dispose() should only ever be used to allow unmanaged resources to be de-allocated early. There is no early when the process stops a millisecond later
This code makes no sense. Don't use it.
It does look non-standard but it is legit. So I wouldn't necessarily call it bad practice, though the fact that it introduces confusion makes it bad practice?
Does this run only as a service or is there console mode? (Console app would not get OnStop called.) Or is there some other (custom) way to stop this service process?
Ammending from my own earlier question of:
I'm not sure why new instead of override, especially since
base.Dispose() is being called.
Reason:
'SomeClass.Dispose()': cannot override inherited member
'System.ComponentModel.Component.Dispose()' because it is not marked
virtual, abstract, or override
In other words, the implementaion of ServiceBase.Dispose is not overridable.
Just to add to the already perfect answers by Hans and Paul: declaring ServiceLauncher2 as IDisposable is redundant, as ServiceBase is a Component which in turn is already IDisposable
I was reading this to understand zend's MVC Request Lifecycle.
But i can't think of any cases in zend where i would use a controller's predispatch method , isn't the init method enough for the code that i want executed before controller's actions .
What should exactly should be in a controller's predispatch and not init .
Can you give an example ?
See Zend_Controller_Action - Object Initialization and the following section Pre and Post Dispatch Hooks. They both go into some detail on the two, and the Action Controller itself.
init() is more for setting up the controller object and doing initialization that will be available to all of your actions. Since init() runs prior to preDispatch(), anything you set up in init() will be available for preDispatch() to use. While it is possible to forward or redirect from init(), it is best practice to do it from preDispatch() because it runs prior to dispatching the controller action.
From the manual:
Note: Usage of init() vs. preDispatch() What is the difference between them (init and preDispatch), and what actions would you take
in each?
The init() method is primarily intended for extending the
constructor. Typically, your constructor should simply set object
state, and not perform much logic. This might include initializing
resources used in the controller (such as models, configuration
objects, etc.), or assigning values retrieved from the front
controller, bootstrap, or a registry.
The preDispatch() method can also be used to set object or
environmental (e.g., view, action helper, etc.) state, but its primary
purpose is to make decisions about whether or not the requested action
should be dispatched. If not, you should then _forward() to
another action, or throw an exception.
Note: _forward() actually will not work correctly when executed from init(), which is a formalization of the intentions
of the two methods.
to extend drew010's answer here is an example of how I use preDispatch() and int():
public function preDispatch() {
$this->_helper->layout->setLayout('admin');
}
/**
*initiaize the flashmessenger and assign the _session property
*/
public function init() {
if ($this->_helper->FlashMessenger->hasMessages()) {
$this->view->messages = $this->_helper->FlashMessenger->getMessages();
}
//set the session namespace to property for easier access
$this->_session = new Zend_Session_Namespace('location');
}
I use preDispatch() to set the layout for every action as it not the default layout and in init() I initialize my flash messenger and setup the session namespace for this controller and initialize the session as a property.
Here's one popular gotcha where you can waste loads of resources using init() instead of preDispatch(): if you do access control using controller plugin's preDispatch() method then call sequence will be: YourController::init(), YourAccessPlugin::preDispatch(), YourController::preDispatch(), YourController::whateverAction. This means that if you do any heavy lifting in init() then unauthorized users can trigger it. Say for e.g. you start a new session namespace in init() then mindless search bots can cause your session database to be littered with empty sessions. So stick to very basic simple stuff in init, avoid touching or modifying any resources, avoid database access.
I am trying to use the OpcRcw.da.dll. If I interop this dll inside a test console project everything works, but if I build dll project to do my interop gymnastic and ref my library into my console project I am getting this error:
COM object that has been separated from its underlying RCW cannot be used.
What need to be done to a class lib project to not kill the RCW ref?
This can happen for a few reasons, the big ones I know of are below.
Event Handlers Without Strong References to the Delegate
A caller subscribes to an event on the com object without keeping a strong reference to the callback delegate. Here is an example of how to do this correctly and how to not do it:
The reason for this is a strong reference needs to be kept to the delegate, if it goes out of scope, the wrapper will release the reference count for the interface and bad things will happen.
public class SomeClass
{
private Interop.ComObjectWrapper comObject;
private event ComEventHandler comEventHandler;
public SomeClass()
{
comObject = new Interop.ComObjectWrapper();
// NO - BAD!
comObject.SomeEvent += new ComEventHandler(EventCallback);
// YES - GOOD!
comEventHandler = new ComEventHandler(EventCallback);
comObject.SomeEvent += comEventHandler
}
public void EventCallback()
{
// DO WORK
}
}
Calls to a disposed Runtime Callable Wrapper
The wrapper has been disposed and calls are being made after it has been disposed. A common way this can happen is if a control is using an activex control or COM object and the controls Dispose() is called out of order.
A form gets Close() called.
System.Windows.Forms.Close() will call Dispose()
Your forms virtual Dispose() will be called which hopefully calls base.Dispose() somewhere. Systems.Windows.Forms.Dispose() will release all COM objects and event syncs on the form, even from child controls.
If the control that owns a com object is explicitly disposed after base.Dispose() and if it calls any methods on it's COM object, these will now fail and you will get the error “COM object that has been separated from its underlying RCW cannot be used”.
Debugging Steps
A good way to debug this issue is to do the following:
Write a class that inherits from the Interop class (otherwise known as the runtime callable wrapper or RCW).
Override DetachEventSink
Override Dispose
Call your new class instead of calling the interop class directly
Add breakpoint to DetachEventSink and Dispose
See who is calling these methods out of order
One other thing
This isn't related to this issue but while we are on the topic, unless you know otherwise, always remember to check that the thread your COM objects are being used from are marked STA. You can do this by breaking in the debugger and checking the value returned from:
Thread.CurrentThread.GetApartmentState();
It's somewhat hard to tell what your actual application is doing, but it sounds like you may be instantiating the COM object and then attempting to access it from another thread, perhaps in a Timer.Elapsed event. If your application is multithreaded, you need to instantiate the COM object within each thread you will be using it in.