How many instances of an Action class are created in Struts 1.x - struts-1

I was searching to know the number of instances created per Action class in Struts 1.x, then I found that it is a Singleton. But I have a doubt: In the action mapping section of struts-config.xml we define the action tag, where there is a scope variable. In that scope variable we can put the value as request, session etc. I wonder that if Action class is a Singleton, then what does this scope variable signify? Does the number of instances per Action class depend upon the scope variable, i.e. if scope is set to "session" the number of instance created depend upon the number of user connected?

The "scope" attribute specifies the scope of the ActionForm only. This allows wizard-like session-based forms to span action mappings, or request-based forms that last only a single request.
There is a single Action instance per mapping (in contrast to an instance per-request, as some frameworks do). Actions should be treated like servlets, and written with thread-safety in mind.

Related

Multiple ViewComponents same Database Request

I've got 3 ViewComponent's which are used to render main, side and footer navigation components for a given layout. However, they all access the same repository for very similar information. My DbContext is injected into the repository. The two alternatives would be to pass all the data in the ViewModel and then (a) pass the necessary object to the ViewComponent, or (b) take some time to convert the ViewComponent functionality into tag helpers.
What I am wondering is whether my current approach will result in instantiating the DbContext 3 times?
No, you will have only one DbContext instance per request (of course only when you register it as manual says).

Why does Grails recommend singleton scope for controllers with actions as methods?

I know early versions of Grails used prototype scope for controllers because actions were all closures at that time.
I know that the current version documentation recommends singleton scoped controllers for controllers that use methods as actions.
From the following post it seems that methods and singleton scope are more desirable or recommended, but it's not clear why.
ttp://grails.1312388.n4.nabble.com/Default-scope-for-controllers-doc-td4657986.html
We have a large project that uses prototype scoped controllers with actions as methods. Changing to the recommended controller scope involves risk and retesting, and removing any non-singleton friendly state from existing controllers.
I'd like to know why does Grails recommend singleton scope for method as actions controllers? Is it just because that's more common and similar to Spring MVC, and avoids confusion, or is there an opportunity for performance improvement, or what? What do I gain if I make the switch to singleton controllers? What is the cost if I don't make the switch?
I haven't worked much with Rails, but (at least in the versions I played with, things may be different now) the controller is the model, containing the data to be rendered by the view. During request handling you store values in controller instance fields before handing off processing to view renderers. So there it makes sense to create a new controller instance for each request so they're distinct.
Grails was inspired by Rails and uses several of its conventions, most famously convention-over-configuration. But the ability to use the controller as the model was also added as a feature, although it wasn't well documented and I doubt many used it.
The typical way a controller action works when using a GSP to render the response (as opposed to forwarding or redirecting, or rendering directly in the controller, e.g. with render foo as JSON) is to return a Map with one or more key/value pairs from the action, and often the return keyword is omitted since it's optional in Groovy:
class MyController {
def someAction() {
def theUser = ...
def theOtherObject = ...
[user: theUser, other: theOtherObject]
}
}
Here the model map has two entries, one keyed by user and the other keyed by other, and those will be the variable names used in the GSP to access the data.
But what most people don't know is that you could also do it like this:
class MyController {
def user
def other
def someAction() {
user = ...
other = ...
}
}
In this case a model map isn't returned from the action, so Grails would populate the model from all properties of the controller class, and in this case the same GSP would work for both approaches since the variable names in the second approach are the same as the map keys in the first.
The option to make controllers singletons was added in 2.0 (technically 1.4 before it was renamed to 2.0, see this JIRA issue) and we also added support for methods as actions in addition to retaining support for closures. The original assumption was that using closures would enable some interesting features, but that never happened. Using methods is more natural since you can override them in subclasses, unlike closures which are just class-scope fields.
As part of the 2.0 rework we removed that Rails-inspired feature on the assumption that since it was essentially undocumented, that the impact on the few odd apps that used the feature wouldn't be significant. I don't recall anyone ever complaining about the loss of that feature.
Although controller classes are typically readily garbage-collectible and creating an instance per request doesn't affect much, it's rare to need per-request state in a controller, so singletons usually make more sense. The default prototype scope was left for backwards compatibility but it's easy to change the default with a Config.groovy property (and the file generated by the create-app script does this).
Although each request does get a new request and response, and if sessions are used each user will have their own, but those are not instance fields of the controllers. They look like they are because we can access request, response, session, params, etc. inside of actions, but those are actually the property access forms of the getRequest(), getResponse(), getSession(), and getParams() methods that are mixed into all controllers during compilation by AST transforms. The methods access their objects not as class fields but via ThreadLocals, so there is per-request state but it's not stored in the controller instance.
I don't remember if there was much in the way of benchmarking to compare using methods versus closures, but Lari Hotari probably did some. If there was a difference it was probably not significant. You could test this in your own application by converting just one or a few controllers and doing before and after tests. If the performance, scaling, and memory differences aren't significant between the two approaches you'll probably be safe staying with prototype score and/or closures. If there is a difference and you don't have instance fields in your controllers, then it'll probably be worth the effort to convert to singletons and methods.
If you do have instance fields they can probably be converted to request attributes - request.foo = 42 is a metaclass shortcut for request.setAttribute('foo', 42), so you could store per-request data safely there instead.

Scoped Regions and View discovery

I have a fairly large prism app and am trying to app a new feature. The feature is a serial port parameter selection.
I want to refresh the list of serial port names when my viewmodel's IsActive property is set to true. This is happily achieved in a sample but reality is...different.
The view i am modifying is contained in an ItemsControl (marked as "SettingsRegion") which is contained in a parent region ( marked as "PageRegion"). Settings region contains settings views from other modules.
I want to use the SyncActiveAwareAttribute for this but it requires scoped regions.
Do I need to use view injection (regionmanager.Regions["blahblah"].Add(....) here or can i get it working using view discovery (regionManager.RegisterWithRegion(...)?
If I have to use injection...
Given that the other modules would need a reference to the scoped IRegionManager instance in order to inject their views:
how is the best way to get the region manager to the other modules?
when should injection take place to ensure that the region exists?
can i mix-and-match injection with discovery? I want to avoid a big refactor.
In order to create Scoped Regions, you would need to use View injection. Related information can be found in the following MSDN Prism Chapter #7 links:
When to Use View Discovery vs. View Injection
Creating Multiple Instances of a Region
The Scoped Region Manager is returned by setting the createScopeRegionManager overloaded parameter as true on the Region.Add() method. You would perform this action in the same place you usually add or register Views into Regions like on the corresponding Module's initialize() method:
IRegionManager scopedRegionManager = scopedRegion.Add(view, null, createScopeRegionManager);
Then, one possible way of sharing the scopedRegionManager to other modules would be to Publish() an event with the scopedRegionManager as a parameter. However, you should be careful with Module dependencies and the Modules instantiation order.
Another approach would be to store the scopedRegionManager into for example, a Dictionary. You can find more related information in the following CodePlex thread:
Scoped Regions in TabControls
It should not be any problem by using View Discovery on other Views registration that would not present Scoped Regions.
I hope this helped you,
Regards.

Is there a reason why the default modelbinder doesn't bind to fields?

I'm using ASP.NET MVC3 and i'm wondering that the default modelbinder binds to public properties but not to public fields.
Normally i just define the model classes with properties but sometimes i use some predefined classes which contains some fields. And everytime i have to debug and remember that the modelbinder just don't like fields.
The question: Whats the reason behind it?
but sometimes i use some predefined classes which contains some fields
While I cannot answer your question about the exact reason why the default model binder works only with properties (my guess is that it respects better encapsulation this way and avoids modifying internal state of the object which is what fields represent) I can say that what you call predefined classes should normally be view models. You should always use view models to and from your controller actions. Those view models are classes that are specifically defined to meet the requirements of the given view.
So back to the main point: fields are supposed to be modified only from within the given class. They should not be accessed directly from the outside. They represent and hold internal state of the class. Properties on the other hand is what should be exposed to the outside world. Imagine that in the property getter/setter you had some custom logic. By modifying directly the field this custom logic would be broken and potentially bring the object into an inconsistent state.
Maybe the reason for ignoring fields is to increase performance of the binder. Instead of searching all the Fields and properties. The Model Binder search for Properties only.
Though I think the Model Binder use cache to improve performance.
DefaultModelBinder exposes a public method:
DefaultModelBinder.BindModel, and a number of protected method available for overriding. All of them listed here.
Besides the model, these method refer to properties only, not fields, like
GetModelProperties,
GetFilteredModelProperties,
GetPropertyValue,
OnXYZValidating,
OnXYZValidated,
OnXYZUpdating,
OnXYZUpdated,
GetXYZValue,
where XYZ stands for either Model, or Property/ies, or both, and so on.
As you can see there is no Fields mentioned with these names whatsoever. As Darin explained no direct changes to Model's state are tolerated by the Binder. Hence no Field in its methods.
And also, you may wish to take a look at another important class: ModelBindingContext. An instance of this class gets passed to the BindModel, and subsequently to BindSimpleModel, and BindComplexModel, depending on model type (string, int,... are considered simple, everything else is complex).
So, this context has the following properties:
ModelXYZ, and
PropertyXYZ.
In other words you have no means to reference the fields in your ViewModel unless you do not override these classes and undertake special actions to do so.
But again, beware of fighting the framework, its always easier to follow it instead.
EDIT: The ModelMetadata class holds all the data needed to bind the model. Its code however, shows no sign of fields, field names, etc. Only properties are referenced and accessed. So, even if you try to inherit and override DefaultModelBinder and ModelBinderContext, you still won't be able to access fiellds, nevermind what their access modifier is: public, private, etc.
Hope this explains most of it.

Magento getSingleton confusion

I'm a little confused about calls I see to Mage::getSingleton, and I'm hoping someone can help me understand a little better.
I have seen a piece of core code that does this:
Mage::getSingleton('customer/session')->isLoggedIn()
I don't know PHP, but I think I can make a safe assumption from the getSingleton method name that there will be only one instance of the class specified (the class being specified as a grouped class name, and resolving to app/code/core/Mage/Customer/Model/Session.php - containing class Mage_Customer_Model_Session.
Question 1 -
How did the getSingleton method know to look in the Model folder for the class?
Question 2 -
So there is one instance of the class for the whole ... I want to say JVM as I am from a Java background, but I'll say PHP engine in the hope that that is vaguely the correct terminology; the Mage_Customer_Model_Session is not passed in a customer id or any such identifier, yet we call the method isLoggedIn()! Give there is not a Mage_Customer_Model_Session instance per customer, how can we ask a singleton if a customer is logged in when we do not tell it what customer we are talking about?
Question 3 -
I've seen calls to Mage::getSingleton('core/session') and to Mage::getSingleton('customer/session') - what is the difference?
Thank you for any help.
First, before we get to Magento, it's important to understand that PHP has a radically different process model than Java.  A PHP singleton (regardless of Magento's involvement) is a single instance of a class per HTTP Request.  A PHP program isn't persistent in memory the same way a Java program is, so adjust your expectations of a "singleton" accordingly.   
Next, it's important to understand that Magento is a framework built on top of PHP, using PHP, and in many cases the original Magento developers wanted to push things towards a more Java like architecture.  So, you're going to see things that look familiar, are familiar, but likely differ in some major way from what you're used to because they still need to hew to PHP's version of the universe. 
Magento uses a factory pattern to instantiate Helpers, Blocks, and "Model" classes.  The string
core/session
is a class alias.  This alias is used to lookup a class name in Magento's configuration. In short, this string is converted into path expressions that search Magento's configuration files to derive a classname, based on the context (helper, block, model) it was called in. For a longer version, see my Magento's Class Instantiation Autoload article.
The concept of a "Model" is a little fuzzy in Magento.  In some cases models are used as domain, or service models.  In other cases they're used as a more traditional middleware database persistence models.  After working with the system for a few years, I think the safest way to think about Models is they're Magento's attempt to do away with direct class instantiation.
There's two ways to instantiate a model class. 
Mage::getModel('groupname/classname');
Mage::getSingleton('groupname/classname');
The first form will get you a new class instance.  The second form will get you a singleton class instance.  This particular Magento abstraction allows you to create a singleton out of any Magento model class, but only if you stick to Magento's instantiation methods.  That is, if you call 
Mage::getSingleton('groupname/classname');
then subsequent calls to 
Mage::getSingleton('groupname/classname');
will return that singleton instance.  (This is implemented with a registry pattern). However, there's nothing stopping you from directly instantiating a new instance of the class with either
$o = Mage::getModel('groupname/classname');
$o = new Mage_Groupname_Model_Classname();
Which brings us to sessions.  PHP's request model, like HTTP, was originally designed to be stateless.  Each request comes into the system with, and only with, information from the user.  As the language (and the web) moved towards being an application platform, a system that allowed information to be persisted was introduced to replace the homegrown systems that were cropping up.  This system was called sessions.  PHP sessions work by exposing a super global $_SESSION array to the end-user-programmer that allow information to be stored on a per web-user basis.  Sessions are implemented by setting a unique ID as a cookie on the user end, and then using that cookie as a lookup key (also standard practice for web applications)
In turn, the Magento system builds an abstraction on top of PHP's session abstraction.  In Magento, you can create a "session model" that inherits from a base session class, set data members on it, and save/load those data members just as you would with a database persistence model.  The difference is information is stored in the session instead of the database store. When you see
core/session
customer/session
these are two different session models, with each one storing different data. One belongs to the Mage_Core module, the other belongs to the Mage_Customer model.  This systems allows modules to safely set and manipulate their own session data, without accidentally stepping on another module's toes, and provide logical class methods for manipulating that data.
Hopefully that answers the questions you asked, as well as the ones you didn't.
Magento's getSingleton is almost the same as getModel. The difference is getModel always returns a new instance of a class, and getSingleton creates a new instance of a class only once and then always returns this instance. See the Mage::getSingleton and Mage::getModel methods.
Magento knows about looking to the Model folder because of configs in the config.xml file (f.e. Mage/Customer/etc/config.xml). See the Magento wiki for developers to know more about config files.
You do not specify customer directly. It's done automatically by Magento in parent classes of Mage_Customer_Model_Session (see Mage_Core_Model_Session_Abstract_Varien::start() method)
Magento has not one session class to discriminate session data. For example, customer ID is stored in Mage_Customer_Model_Session and error flash message 'Product is not available' will be stored in the Mage_Catalog_Model_Session class.

Resources