Imagine in the Global.asax.cs file I had an instance class as a private field. Let's say like this:
private MyClass _myClass = new MyClass();
And I had a static method on Global called GetMyClass() that gets the current HttpApplication and returns that instance.
public static MyClass GetMyClass()
{
return ((Global)HttpContext.Current.ApplicationInstance)._myClass;
}
So I could get the instance on the current requests httpapplication by calling Global.GetMyClass().
Keep in mind that there is more than one (Global) HttpApplication. There is an HttpApplication for each request and they are pooled/shared, so in the truest sense it is not a real singleton. But it does follow the pattern to a degree.
So as the question asked, would you consider this at the very least the singleton pattern?
Would you say it should not be used? Would you discourage its use? Would you say it's a possibly bad practice like a true singleton.
Could you see any problems that may arise from this type of usage scenario?
Or would you say it's not a true singleton, so it's OK, and not bad practice. Would you recommend this as a semi-quasi singleton where an instance per request is required? If not what other pattern/suggestion would you use/give?
Have you ever used anything such as this?
I have used this on past projects, but I am unsure if it's a practice I should stay away from. I have never had any issues in the past though.
Please give me your thoughts and opinions on this.
I am not asking what a singleton is. And I consider a singleton bad practice when used improperly which is in many many many cases. That is me. However, that is not what I am trying to discuss. I am trying to discuss THIS scenario I gave.
Whether or not this fits the cookie-cutter pattern of a Singleton, it still suffers from the same problems as Singleton:
It is a static, concrete reference and cannot be substituted for separate behavior or stubbed/mocked during a test
You cannot subclass this and preserve this behavior, so it's quite easy to circumvent the singleton nature of this example
I'm not a .NET person so I'll refrain from commenting on this, except for this part:
Would you say its bad practice like a true singleton.
True singletons aren't 'bad practice'. They're HORRIBLY OVERUSED but that's not the same thing. I read something recently (can't remember where, alas) where someone pointed out the -- 'want or need' vs. 'can'.
"We only want one of these", or "we'll only need one": not a singleton.
"We CAN only have one of these": singleton
That is, if the very idea of having two of that object will break something in horrible and subtle ways, yes, use a singleton. This is true a lot more rarely than people think, hence the proliferation of singletons.
A Singleton is an object, of which, there CAN BE only one.
Objects of which there just happens to be one right now are not singleton.
Since you're talking about a web application, you need to be very careful with assuming anything with static classes or this type of pseudo-singleton because as David B said, they are only shared across that thread. Where you will get in trouble is if IIS is configured to use more than one worker process (configured with the ill-named "Web-Garden" mode, but also the # worker processes can be set in machine.config). Assuming the box has more than one processor, whoever is trying to tweak it's performance is bound to turn this on.
A better pattern for this sort of thing is to use the HttpCache object. It is already thread-safe by nature, but what still catches most people is you object also needs to be thread-safe (since you're only going to probably create the instance and then read/write to a lot of its properties over time). Here's some skeleton code to give you an idea of what I'm talking about:
public SomeClassType SomeProperty
{
get
{
if (HttpContext.Current.Cache["SomeKey"] == null)
{
HttpContext.Current.Cache.Add("SomeKey", new SomeClass(), null,
System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromDays(1),
CacheItemPriority.NotRemovable, null);
}
return (SomeClassType) HttpContext.Current.Cache["SomeKey"];
}
}
Now if you think you might need a web farm (multi-server) scale path, then the above won't work as the application cache isn't shared across machines.
Forget singleton for a moment.
You have static methods that return application state. You better watch out.
If two threads access this shared state... boom. If you live on the webserver, your code will eventually be run in a multi-threaded context.
I would say that it is definitely NOT a singleton. Design patterns are most useful as definitions of common coding practices. When you talk about singletons, you are talking about an object where there is only one instance.
As you yourself have noted, there are multiple HttpApplications, so your code does not follow the design of a Singleton and does not have the same side-effects.
For example, one might use a singleton to update currency exchange rates. If this person unknowingly used your example, they would fire up seven instances to do the job that 'only one object' was meant to do.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
At work, our service calls follow the pattern of:
Create a proxy that allows you to hit a service on our business tier
upon hitting the service, it creates a new response instance
instantiates a new instance of one of our business code classes
Assigns the result of calling whatever function on the new instance to the response
Returns the response back through the proxy
So it always looks like this:
Dim someRequest as Request = CreateSomeSortOfRequest()
Dim results as Response = Nothing
using proxy as IResultProxy = OurLibrary.Proxy(Of IResultProxy).Create()
results = proxy.GetResults(request)
End Using
Then:
Dim results as Response = Nothing
Using whateverBusiness as new BusinessClass
results = whateverBusiness.ComputeWhatever(request)
End Using
Return results
Pretty basic stuff, right? Well the guys who have worked there for a little over 20 years now will go on and on about how none of these business classes should ever have any member variables of any kind. Ever. Wanna perform some really complicated operation? Better be prepared to pass 10 to (and I've seen it) 30 parameters.
All of this, to me, seems like bad practice. As long as you remain in that narrow scope, hand off a request to a new instance of a business class, ask it to perform whatever, it performs whatever logic necessary within itself, return the result, and carry on with your day.
I've investigated and we only ever use threading ourselves in one location in the system, and that just fires off different service calls (all of which follow the above pattern). We don't use instance pools, static variables, or anything else like that, especially since we have the above stated issue that we have a running belief that there should never be any class scoped variables.
Am I crazy for thinking that having these classes with extremely tight and locked down entry points (i.e. no outside access to internal variables) is perfectly fine, especially since there is no way to access the instances of the business class outside the scope of the service call? Or are my elders correct for stating that any private member variable in a class is non-threadsafe and should never be used?
I guess I should mention that the business classes pretty much always load some data from the database, try to piece that data together into, often, very deep hierarchal structures, then return (or the opposite; taking the object, breaking it apart, and performing, sometimes, hundreds of database calls to save).
Wanna perform some really complicated operation? Better be prepared to pass 10 to (and I've seen it) 30 parameters
Sounds like they don't want any state (public anyway) on their business classes, an understandably noble vision as it is but rarely does it prove to be useful or practical as a general rule. Instead of 30 parameters, maybe they should pass in a struct or request class.
You could point out to them that in their effort to prevent state, that 10-30 parameters comes with its own set of problems.
As stated in the documentation for the brilliant code analysis tool nDepend:
nDepend:
NbParameters: The number of parameters of a method. Ref and Out are also counted. The this reference passed to instance methods in IL is not counted as a parameter.
Recommendations: Methods where NbParameters is higher than 5 might be painful to call and might degrade performance. You should prefer using additional properties/fields to the declaring type to handle numerous states. Another alternative is to provide a class or structure dedicated to handle arguments passing (for example see the class System.Diagnostics.ProcessStartInfo and the method System.Diagnostics.Process.Start(ProcessStartInfo)) - Holy swiss cheese Batman, tell me more.
It's arguably no different to when the client passes a request object to the WCF service. You are passing request objects aren't you?
OP:
Am I crazy for thinking that having these classes with extremely tight and locked down entry points (i.e. no outside access to internal variables) is perfectly fine
OK it sounds like the system has been around for a while and has had some best practices applied by your elders during its construction. That's good. However such a system is arguably only going to continue being robust as someone follows what-ever rules that were setup...and from what you say sound quite bizarre and somewhat ill-informed.
It might also be an example of accidental architecture where the system is just because it is.
e.g. if someone goes and adds a public method and say some public properties or makes what was a private field public is likely to upset the applecart.
I once had the misfortune of working on a legacy system and though it appeared to run without incident, it was all rather fragile due to the exorbitant amount of public fields. (mind you this was c++!)
Someone could have said:
"well don't touch the public fields"
to which I could reply:
"well maybe we shouldn't make the fields public"
Hence their desire to have no instance fields. The notion that c# classes with "member variables of any kind" is naughty is not the real source of concern. Instead I suspect the problem is that of thread safety and for that they should be looking into how the caller or callers be made thread-safe not the business class in this case.
Enforcing thread safety by not having state, though effective is kind of a sledgehammer approach and tends to annoy other parts of OO sub-systems.
WCF Threading Models
It sounds to me they are performing applying old-school threading protection in WCF where WCF has it's own way of guaranteeing thread-safety in a way quite similar to how the Apartment model was successful for COM.
Instead of worrying about lock()s; and synchronisation, why not let WCF serialise calls for you:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
ConcurrencyMode = ConcurrencyMode.Single)]
public partial class MyService: IMyService, IDisposable
{
// ...
}
InstanceContextMode.PerSession essentially tells WCF to create a unique private instance of the service per client proxy. Got two clients calling? Well that means two instances of MyService will be created. So irrespective of what instance members this class has its guaranteed not to trod on the other instance. (note I don't refer to statatics here)
ConcurrencyMode = ConcurrencyMode.Single tells WCF that calls to this service instance must be serialised one after the other and that concurrent calls to the service are not allowed. This ties in with the InstanceContextMode setting.
Just by setting these two but very powerful settings in WCF you have told it to not only create private instances of your WCF service such that multiple clients can't trod on it, but that even if the client shared it's client proxy in a thread and attempted to call one particular service instance concurrently, WCF guarentees that calls to the service will be serialised safely.
What does this mean?
Feel free to add instance fields or properties to your service class
such members won't be trodden on by other threads
when using WCF, there is generally no need for explicit thread locking in your service class (depending on your app, this could apply to subsequent calls. see below)
It does not mean that per-session-single services only ever allow one client at a time. It means only one call per client proxy at a time. Your service will most likely have multiple instances running at a particular moment having a jolly good time in the knowledge that one can't throw stones at the other.
Roll-on effects
As long as you remain in that narrow scope, hand off a request to a new instance of a business class
Since WCF has established a nice thread-safe ecosystem for you, it has a nice follow-on effect elsewhere in the call-stack.
With the knowledge that your service entry point is serialised, you are free to instantiate the business class and set public members if you really wanted to. It's not as if another thread can access it anyway.
Or are my elders correct for stating that any private member variable in a class is non-threadsafe
That depends entirely on how the class is used elsewhere. Just as a well designed business processing layer should not care whether the call stack came from WCF; a unit test; or a console app; there may be an argument for threading neutrality in the layer.
e.g. let's say the business class has some instance property. No drama, the business class isn't spawning threads. All the business class does is fetch some DB data; has a fiddle and returns it to the caller.
The caller is your WCF service. It was the WCF service that created an instance of the business class. But what's that I hear you say - "the WCF service instance is already thread-safe!" Exactly right and thank-you for paying attention. WCF already set up a nice thread safe environment as mentioned and so any instance member in the business class shouldn't get obliterated by another thread.
Our particular WCF thread is the only thread that is even aware of this particular business class's instance.
Conclusion
Many classes in .NET have state and many of those are in private fields. That doesn't mean it's bad design. It's how you use the class that requires thought.
A WinForms Font or Bitmap object has both state; I suspect even with private members; and shouldn't arguably be fiddled with concurrently by multiple threads. That's not a demonstration of poor design by Microsoft's part rather something that should have state.
That's two classes created by people much smarter than you, me and your elders I suspect, in a codebase larger than anything we will ever work on.
I think it is fantastic that you are questioning your elders. Sometimes we don't always get it right.
Keep it up!
See Also
Lowy, Juval, "Programming WCF Services: Mastering WCF and the Azure AppFabric Service Bus", Amazon. The WCF bible - a must read for prior to any serious dabbling into WCF goodness
nDepend, a truly marvelous and powerful code analysis tool. Though one may be forgiven into thinking it's a FxCop-type-tool and though it does support such a feature, it does that and more. It analyses your entire Visual Studio solution (and stand-alone libraries if you wish) investigating coupling for one and excessive use of parameters as another. Be prepared for it pointing out some embarrassing mistakes made by the best of us.
Comes with some groovy charts too that look impressive on any dashboard screen.
Ok so I was just thinking to myself why do programmers stress so much when it comes down to Access Modifiers within OOP.
Lets take this code for example / PHP!
class StackOverflow
{
private var $web_address;
public function setWebAddress(){/*...*/}
}
Because web_address is private it cannot be changed by $object->web_address = 'w.e.', but the fact that that Variable will only ever change is if your programme does $object->web_address = 'w.e.';
If within my application I wanted a variable not to be changed, then I would make my application so that my programming does not have the code to change it, therefore it would never be changed ?
So my question is: What are the major rules and reasons in using private / protected / non-public entities
Because (ideally), a class should have two parts:
an interface exposed to the rest of the world, a manifest of how others can talk to it. Example in a filehandle class: String read(int bytes). Of course this has to be public, (one/the) main purpose of our class is to provide this functionality.
internal state, which noone but the instance itself should (have to) care about. Example in a filehandle class: private String buffer. This can and should be hidden from the rest of the world: They have no buisness with it, it's an implementation detail.
This is even done in language without access modifiers, e.g. Python - except that we don't force people to respect privacy (and remember, they can always use reflection anyway - encapsulation can never be 100% enforced) but prefix private members with _ to indicate "you shouldn't touch this; if you want to mess with it, do at your own risk".
Because you might not be the only developer in your project and the other developers might not know that they shouldn't change it. Or you might forget etc.
It makes it easy to spot (even the compiler can spot it) when you're doing something that someone has said would be a bad idea.
So my question is: What are the major rules and reasons in using private / protected / non-public entities
In Python, there are no access modifiers.
So the reasons are actually language-specific. You might want to update your question slightly to reflect this.
It's a fairly common question about Python. Many programmers from Java or C++ (or other) backgrounds like to think deeply about this. When they learn Python, there's really no deep thinking. The operating principle is
We're all adults here
It's not clear who -- precisely -- the access modifiers help. In Lakos' book, Large-Scale Software Design, there's a long discussion of "protected", since the semantics of protected make subclasses and client interfaces a bit murky.
http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620
Access modifiers is a tool for defensive programming strategy. You protect your code consciously against your own stupid errors (when you forget something after a while, didn't understand something correctly or just haven't had enough coffee).
You keep yourself from accidentally executing $object->web_address = 'w.e.';. This might seem unnecessary at the moment, but it won't be unnecessary if
two month later you want to change something in the project (and forgot all about the fact that web_address should not be changed directly) or
your project has many thousand lines of code and you simply cannot remember which field you are "allowed" to set directly and which ones require a setter method.
Just because a class has "something" doesn't mean it should expose that something. The class should implement its contract/interface/whatever you want to call it, but in doing so it could easily have all kinds of internal members/methods that don't need to be (and by all rights shouldn't be) known outside of that class.
Sure, you could write the rest of your application to just deal with it anyway, but that's not really considered good design.
I found something funny, I notice it by luck while I was debugging other thing. I was applying MVP pattern and I made a singleton controller to be shared among all presentations.
Suddenly I figured out that some event is called once at first postback, twice if there is two postback, 100 times if there is 100 postbacks.
because Singleton is based on a static variable which hold the instance, and the static variable live across postbacks, and I wired the event assuming that it will be wired once, and rewired for each postback.
I think we should think twice before applying a singleton in a web application, or I miss something??
thanks
I would think twice about using a Singleton anywhere.
Many consider Singleton an anti-pattern.
Some consider it an anti-pattern, judging that it is overused, introduces unnecessary limitations in situations where a sole instance of a class is not actually required, and introduces global state into an application.
There are lots of references on Wikipedia that discuss this.
It is very rare to need a singleton and personally I hold them in the same light as global variables.
You should think twice any time you are using static objects in a multi-threaded application (not only the singleton pattern) because of the shared state. Proper locking mechanisms should be applied in order to synchronize the access to the shared state. Failing to do so some very difficult to find bugs could appear.
I've been using Singletons in my web apps for quite some time and they have always worked out quite well for me, so to say they're a bad idea is really a pretty difficult claim to believe. The main idea, when using Singletons, is to keep all the session-specific information out of them, and to use them more for global or application data. To avoid them because they are "bad" is really not too smart because they can be very useful when applied correctly.
I'm looking at some vb.net code I just inherited, and cannot fathom why the original developer would do this.
Basically, each "Domain" class is a collection of properties. And each one implements IDisposable.Dispose, and overrides Finalize(). There is no base class, so each just extents Object.
Dispose sets each private var to Nothing, or calls _private.Dispose when the property is another domain object. There's a private var that tracks the disposed state, and the final thing in Dispose is GC.suppressFinalize(Me)
Finalize just calls Me.Dispose and MyBase.Finalize.
Is there any benefit to this? Any harm? There are no un-managed resources, no db connections, nothing that would seem to need this.
That strikes me as being a VB6 pattern.
I would bet the guy was coming straight from VB6, maybe in the earlier days of .NET when these patterns were not widely understood.
There also is one case were setting an nternal reference to nothing is useful in a call to Dispose: when the member is marked as Withevents.
Without that, you risk having an uncollected object handling events when it really should not be doing that anymore.
It would seem to me that this is something that is NOT needed at all, especially without un-managed resources and data connections.
If you happen to be able to sanitize and post the code we might be able to get a bit more insight, but realistically I can't see a need for it.
Depending on the size of the objects, and how often they are created/destroyed, it could be to ensure GC can happen as early as possible.
It may be, that this pattern was used in other projects and it continues on without understanding why it was used in the first place. Monkey Gardeners
The only reason that I could see for this -- and this is dubious at best -- is if these things are being created and disposed of higher in the "food chain" and there is a potential for some of these domain classes to have either a limited or unmanaged resource at some point.
Even that is sketchy...it sounds like someone came from an unmanaged background and was looking for the .NET equivalent to managing your memory and came across the IDisposable interface.
I have recently inherited an ASP.Net app using Linq2SQL. Currently, it has its DataContext objects declared as static in every page, and I create them the first time I find they are null (singleton, sort of).
I need comments if this is good or bad. In situations when I only need to read from the DB and in situations where i need to write as well.
How about having just one DataContext instance for the entire application?
One DataContext per application would perform badly, I'm afraid. The DataContext isn't thread safe, for starters, so even using one as a static member of a page is a bad idea. As asgerhallas mentioned it is ideal to use the context for a unit of work - typically a single request. Anything else and you'll start to find all of your data is in memory and you won't be seeing updates without an explicit refresh. Here are a couple posts that talk to those two subjects: Identity Maps and Units of Work
I use to have one DataContext per request, but it depends on the scenarios you're facing.
I think the point with L2S was to use it with the unit of work pattern, where you have a context per ... well unit of work. But it doesn't work well in larger applications as it's pretty hard to reattach entities to a new context later.
Rick Strahl has a real good introduction to the topic here:
http://www.west-wind.com/weblog/posts/246222.aspx
One thing I can say I have had problems with in the past, is to have one context to both read and write scenarios. The change tracking done in the datacontext is quite an overhead when you are just reading, which is what most webapps tends to do most of the time. You can make the datacontext readonly and it will speed up things quite a bit - but then you'll need another context for writing.