Related
I'm using dependency injection in my C# projects and generally everything is ok.
Nevertheless, I often hear the rule "constructor must only consist of trivial operations - assign dependencies and do nothing more" I.e:
//dependencies
interface IMyFooDependency
{
string GetBuzz();
int DoOtherStuff();
}
interface IMyBarDependency
{
void CrunchMe();
}
//consumer
class MyNiceConsumer
{
private readonly IMyFooDependency foo;
private readonly IMyBarDependency bar;
private /*readonly*/ string buzz;//<---question here
MyNiceConsumer(IMyFooDependency foo, IMyBarDependency bar)
{
//omitting null checks
this.foo = foo;
this.bar = bar;
//OR
this.buzz = foo.GetBuzz();//is this a bad thing to do?
}
}
UPD: assume IMyFooDependency can't be replaced with the GetBuzz(), as in that case the answer is obvious: "do not depend on foo".
UPD2: Please, understand that this question is not about eliminating dependency from foo in a hypothetic code, but about understanding a principle of good constructor design.
So, my questions is following: is this really a bad pattern to include non-trivial logic in constructor(i.e. obtaining buzz value, making some calculations based on dependencies.)
Personally I, unless lazy load is necessary, would include foo.GetBuzz() in constructor, as object need to be initialized after call to its constructor.
The only drawback I see: by including non-trivial logic you increase the number of places where something might go wrong, and you'll get an obfuscated error message from your IoC container(but same things happen in case of invalid parameter, so the drawback is rather minor)
Any other considerations for eliding non-trivial constructors?
If you need IMyFooDependency only for buzz creation, then you actually need buzz:
class MyNiceConsumer
{
private readonly IMyBarDependency bar;
private readonly string buzz;
MyNiceConsumer(string buzz, IMyBarDependency bar)
{
this.buzz = buzz;
this.bar = bar;
}
}
And create instance of nice consumer this way:
new MyNiceConsumer(foo.GetBuzz(), bar);
I don't see any difference between obtaining buzz before passing parameters to constructor, or obtaining it inside constructor. Same value will be returned from repository. So, you don't need to depend on repository.
UPDATE: Technically there is nothing wrong with complex initialization logic in constructor. Take a look on winforms InitializeComponent method, where all controls are created, initialized and added to form.
But it violates SRP (creation and initialization) and its hard to test. You can read more about this flaw on writing testable code guide. Main idea:
Do not create collaborators in your constructor, but pass them in.
(Don’t look for things! Ask for things!)
The rationale for not doing any work in the constructor comes from looking at the execution of the program in two phases. The first phase is to wire up your object graph. The second phase is to do the "real work".
There is a tension between this ideal and efficiently maintaining a class's invariants and internal state. The less setup you can do in your constructor, the more difficult all of your methods will be to implement because they must take into account the varying possible internal state of the object. Remember, the constructor is the only code you can be sure is called for an object.
The way out of this conundrum is to realize that an object's "real work" is defined by it's interface and behavior in relation to other objects. That is, the dependencies provided to the constructor and objects provided as arguments to methods later down the road.
Feel free to do any kind of setup you like in your constructor that does not have a noticeable effect on other objects in your system. Likewise, be very sensitive to timing issues in your object's construction.
If you determine that a File object can't exist without a filename provided by the user: don't call keyboard.filename_from_keyboard() in the constructor. Instead you design your system such that the object is created by a factory (provider) during execution with the filename provided to the constructor or you allow the File object to exist without a filename. Maybe it can get it's own filename during execution? This is part of managing your object's lifetime and it's the hardest part IMO. This gets very subtle because "real work" involves creating objects too. But I digress...
In your example you would have to decide if foo.GetBuzz() breaks that condition. If GetBuzz() is a referentially transparent function, you're almost always in the clear to call it in the constructor. If GetBuzz() involves any I/O, user interaction or changes any noticeable internal state of any other object, then it is probably does not need to be called from a constructor.
As lazyberezovsky rightly mentioned, don't look for things! Ask for things!
If the creating code (let's say, MyNiceCreator) treats foo as an opaque value and news up MyNiceConsumer, then most likely creation should not be the responsibility of MyNiceCreator. The code that creates the MyNiceConsumer instance must be able to give the required values to the constructor.
A better pattern:
MyNiceCreator should "ask" for a MyNiceConsumer instance. This way the creation of MyNiceConsumer instance will be the responsibility of the appropriate class.
It seems that in most cases the C# compiler could call Dispose() automatically. Like most cases of the using pattern look like:
public void SomeMethod()
{
...
using (var foo = new Foo())
{
...
}
// Foo isn't use after here (obviously).
...
}
Since foo isn't used (that's a very simple detection) and since its not provided as argument to another method (that's a supposition that applies to many use cases and can be extended), the compiler could automatically and immediately call Dispose() without the developper requiring to do it.
This means that in most cases the using is pretty useless if the compiler does some smart job. IDisposable seem low level enough to me to be taken in account by a compiler.
Now why isn't this done? Wouldn't that improve the performances (if the developpers are... dirty).
A couple of points:
Calling Dispose does not increase performance. IDisposable is designed for scenarios where you are using limited and/or unmanaged resources that cannot be accounted for by the runtime.
There is no clear and obvious mechanism as to how the compiler could treat IDisposable objects in the code. What makes it a candidate for being disposed of automatically and what doesn't? If the instance is (or could) be exposed outside of the method? There's nothing to say that just because I pass an object to another function or class that I want it to be usable beyond the scope of the method
Consider, for example, a factory patter that takes a Stream and deserializes an instance of a class.
public class Foo
{
public static Foo FromStream(System.IO.Stream stream) { ... }
}
And I call it:
Stream stream = new FileStream(path);
Foo foo = Foo.FromStream(stream);
Now, I may or may not want that Stream to be disposed of when the method exits. If Foo's factory reads all of the necessary data from the Stream and no longer needs it, then I would want it to be disposed of. If the Foo object has to hold on to the stream and use it over its lifetime, then I wouldn't want it to be disposed of.
Likewise, what about instances that are retrieved from something other than a constructor, like Control.CreateGraphics(). These instances could exist outside of the code, so the compiler wouldn't dispose of them automatically.
Giving the user control (and providing an idiom like the using block) makes the user's intention clear and makes it much easier to spot places where IDisposable instances are not being properly disposed of. If the compiler were to automatically dispose of some instances, then debugging would be that much more difficult as the developer had to decipher how the automatic disposal rules applied to each and every block of code that used an IDisposable object.
In the end, there are two reasons (by convention) for implementing IDisposable on a type.
You are using an unmanaged resource (meaning you're making a P/Invoke call that returns something like a handle that must be released by a different P/Invoke call)
Your type has instances of IDisposable that should be disposed of when this object's lifetime is over.
In the first case, all such types are supposed to implement a finalizer that calls Dispose and releases all unmanaged resources if the developer fails to do so (this is to prevent memory and handle leaks).
Garbage Collection (while not directly related to IDisposable, is what cleans up unused objects) isn't that simple.
Let me re-word this a little bit. Automatically calling Dispose() isn't that simple. It also won't directly increase performance. More on that a little later.
If you had the following code:
public void DoSomeWork(SqlCommand command)
{
SqlConnection conn = new SqlConnection(connString);
conn.Open();
command.Connection = conn;
// Rest of the work here
}
How would the compiler know when you were done using the conn object? Or if you passed a reference to some other method that was holding on to it?
Explicitly calling Dispose() or using a using block clearly states your intent and forces things to get cleaned up properly.
Now, back to performance. Simply calling Dispose() on an Object doesn't guarantee any performance increase. The Dispose() method is used for "cleaning up" resources when you're done with an Object.
The performance increase can come when using un-managed resources. If a managed object doesn't properly dispose of its un-managed resources, then you have a memory leak. Ugly stuff.
Leaving the determination to call Dispose() up to the compiler would take away that level of clarity and make debugging memory leaks caused by un-managed resources that much more difficult.
You're asking the compiler to perform a semantic analysis of your code. The fact that something isn't explicitly referenced after a certain point in the source does not mean that it isn't being used. If I create a chain of references and pass one out to a method, which may or may not store that reference in a property or some other persistent container, should I really expect the compiler to trace through all of that and figure out what I really meant?
Volatile entities may also be a concern.
Besides, using() {....} is more readable and intuitive, which is worth a lot in terms of maintainability.
As engineers or programmers, we strive to be efficient, but that is rarely the same thing as lazy.
Look at the MSDN Artilce for the C# Using Statement The using statement is just a short cut to keep from doing a try and finally in allot of places. Calling the dispose is not a low level functionality like Garbage Collection.
As you can see using is translated into.
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
How would the compiler know where to put the finally block? Does it call it on Garbage Collection?
Garabage Collection doesn't happen as soon as you leave a method. Read this article on Garbage Collection to understand it better. Only after there are no references to the object. A resource could be tied up for much longer than needed.
The thought that keeps popping into my head is that the compiler should not protect developers who do not clean up there resources. Just because a language is managed doesn't mean that it is going to protect from yourself.
C++ supports this; they call it "stack semantics for reference types". I support adding this to C#, but it will require different syntax (changing the semantics based on whether or not a local variable is passed to another method isn't a good idea).
I think that you are thinking about finalizers. Finalizers use the destructor syntax in c#, and they are called automatically by the garbage collector. Finalizers are only appropriate to use when you are cleaning up unmanaged resources.
Dispose is intended to allow for early cleanup of unmanaged resources (and it can be used to clean managed resources as well).
Detection is actually trickier than it looks. What if you have code like this:
var mydisposable = new...
AMethod(mydisposable);
// (not used again)
It's possible that some code in AMethod holds on to a reference to myDisposable.
Maybe it gets assigned to an instance variable inside of that method
Maybe myDisposable subscribes to an event inside of AMethod (then the event publisher holds a reference to myDisposable)
Maybe another thread is spawned by AMethod
Maybe mydisposable becomes "enclosed" by an anonymous method or lamba expression inside of AMethod.
All of those things make it difficult to know for absolute certain that your object is no longer in use, so Dispose is there to let a developer say "ok, I know that it's safe to run my cleanup code now);
Bear in mind also that dispose doesn't deallocate your object -- only the GC can do that. (The GC does have the magic to understand all of the scenarios that I described, and it knows when to clean up your object, and if you really need code to run when the GC detects no references, you can use a finalizer). Be careful with finalizers, though -- they are only for unmanaged allocations that your class owns.
You can read more about this stuff here:
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
and here: http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx
If you need unmanaged handle cleanup, read about SafeHandles as well.
It's not the responsibility of the compiler to interpret the scopes in your application and do things like figure out when you no longer need memory. In fact, I'm pretty sure that's an impossible problem to solve, because there's no way for the compiler to know what your program will look like at runtime, no matter how smart it is.
This is why we have the garbage collection. The problem with garbage collection is that it runs on an indeterminate interval, and typically if an object implements IDisposable, the reason is because you want the ability to dispose of it immediately. Like, right now immediately. Constructs such as database connections aren't just disposable because they have some special work to do when they get trashed - it's also because they are scarce.
I seems difficult for the G.C. to know that you won't be using this variable anymore later in the same method. Obviously, if you leave the method, and don't keep a further reference to you variable, the G.C. will dispose it. But using using in you sample, tells the G.C. that you are sure that you will not be using this variable anymore after.
The using statement has nothing to do with performance (unless you consider avoiding resource/memory leaks as performance).
All it does for you is guarantee that the IDisposable.Dispose method is called on the object in question when it goes out of scope, even if an exception has occurred inside the using block.
The Dispose() method is then responsible for releasing any resources used by the object. These are most often unmanaged resources such as files, fonts, images etc, but could also be simple "clean-up" activities on managed objects (not garbage collection however).
Of course if the Dispose() method is implemented badly, the using statement provides zero benefit.
I think the OP is saying "why bother with 'using' when the compiler should be able to work it out magically pretty easily".
I think the OP is saying that
public void SomeMethod()
{
...
var foo = new Foo();
... do stuff with Foo ...
// Foo isn't use after here (obviously).
...
}
should be equivalent to
public void SomeMethod()
{
...
using (var foo = new Foo())
{
... do stuff with Foo ...
}
// Foo isn't use after here (obviously).
...
}
because Foo isn't used again.
The answer of course is that the compiler cannot work it out pretty easily. Garbage Collection (what magically calls "Dispose()" in .NET) is a very complicated field. Just because the symbol isn't being used below that doesn't mean that the variable isn't being used.
Take this example:
public void SomeMethod()
{
...
var foo = new Foo();
foo.DoStuffWith(someRandomObject);
someOtherClass.Method(foo);
// Foo isn't use after here (obviously).
// Or is it??
...
}
In this example, someRandomObject and someOtherClass might both have references to what Foo points out, so if we called Foo.Dispose() it would break them. You say you're just imagining the simple case, but the only 'simple case' where what you're proposing works is the case where you make no method calls from Foo and do not pass Foo or any of its members to anything else - effectively when you don't even use Foo at all in which case you probably have no need to declare it. Even then, you can never be sure that some kind of reflection or event hackery didn't get a reference to Foo just by its very creation, or that Foo didn't hook itself up with something else during its constructor.
In addition to the fine reasons listed above, since the problem can't be solved reliably for all cases, those "easy" cases are something that code analysis tools can and do detect. Let the compiler do stuff deterministically, and let your automatic code analysis tools tell you when you're doing something silly like forgetting to call Dispose.
What is the performance concern with static method over non-static methods? I have read that Static methods are better in terms of performance but i want to know, how they are faster? If a method is not using any instance member then our compiler should take care of it and treat it as static method.
Edit: Eric comments more on this here, and hints that there are some times when call is used... although note that his new() example isn't guaranteed ;-p
In the original compiler (pre-1.1), the compiler did treat non-virtual instance methods (without this) as static; the problem was that this lead to some odd problems with null checking, i.e.
obj.SomeMethod();
didn't threw an exception (for obj=null and non-virtual method SomeMethod which didn't touch this). Which was bad if you ever changed the implementation of SomeMethod. When they investigated the cost of adding the explicit null check (i.e. null-check then static-call), it turned out to be just the same as using a virtual-call, so they did that instead, which makes it far more flexible and predictable.
Note that the "don't throw an exception" is also entirely the behaviour if SomeMethod is an extension-method (static).
I think at one point you could emit IL to invoke a regular instance method via static-call, but the last time I tried I got the "oh no you don't!" message from the CLR (this operation may destabilise the runtime); either they blocked this entirely, or (perhaps more likely) I borked the custom IL.
Yes a static call would be faster - you don't need to create an instance of the object before you call the method. (Although you obviously won't notice the difference)
In practical terms it doesn't matter if the compiler optimizes a method (makes the instance method static) - you won't call the instance method unless you've already created the instance already, right?
At the end of the day you should rather try to optimize your code for maintainability rather than trying to save 3 nanoseconds here or there.
See this question.
Here's the excerpt:
a static call is 4 to 5 times faster
than constructing an instance every
time you call an instance method.
However, we're still only talking
about tens of nanoseconds per call
I doubt the compiler will treat it as a static method, although you can check for yourself. The benefit would be no creation of the instance. No garbage collector to worry about. And only the static constructor to be called, if there is one.
static methods fast,because constructing an instance
buy if you only create a instance and save static member , performance is equal
they are very small in total performance
so .......
yes static method is fast but the memory acquired by the static variable is not controlled by GC and is not released even if it is not needed, so that is an issue.
but more than anything else you should consider the design of the allpication as the memory and speed has increased by days but your design may suck if you dont make use of static variables properly.
While reading Jon Skeet's article on singletons in C# I started wondering why we need lazy initialization in a first place. It seems like the fourth approach from the article should be sufficient, here it is for reference purposes:
public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
In the rare circumstances, where you have other static methods on a singleton, lazy initialization may have benefits, but this is not a good design.
So can people enlighten me why lazy initialization is such a hot thing?
In those scenarios where whatever it is you are initializing might not be needed at all, and is expensive to initialize, (in terms of CPU cycles or resources), then implementing a lazy initializor saves that cost in those cases where the object is not required.
If the object will always be required, or is relatively cheap to initialize, then there is no added benefit from a lazy initializer.
In any event, implementing a lazy initializer improperly can make a singleton non-thread-safe, so if you need this pattern, be careful to do it correctly. Jon's article has a pattern, (I think it's the last one), that addresses this issue.
You don't need lazy initialization on a singleton, if the only reason you're going to use that type is to reference the instance.
If, however, you reference any other property or method on the type, or the type itself, you will initialize the singleton.
Granted, good design would leave one task for one type, so this shouldn't be a problem. If you make your singleton class to "complex", however, lazy initialization can help keep you from having consequences due to initializing too soon.
I'm not sure that this applies to C# as well, but I'll answer for C++:
One of the ideas behind Singletons is that the order of initialization of static objects is undefined. So if you have a static class that tries to use another static class, you might be in trouble.
A concrete example: Let's say I have a Log class, which I decided to implement as a Singleton. Let's also assume I have a method called LoadDB, which for whatever reason, is a static called at the start of the program. Assuming LoadDB decides it needs to log something, it will call the Singleton. But since the order of static initialization is undefined, it might be doing something that's an error.
A Singleton fixes this, since once you call GetInstance(), no matter where you are in the initialization process, the object is guaranteed to exist.
Again, I don't know if this is relevant, but at least that's the history of it (as far as I remember).
From Java DI perspective, lazy initialization is good, there are always (say, spring) beans in another API that you might not want to use, for example, an eagerly loaded singleton cache (something that is shared with everyone using the cache) might not be needed for you although it may be referred as a dependency in your same code. Whats the point in loading the singleton wasting resources?
The lazy initialization implementation choice is tricky, in spring, would you choose lazy-init="true" (spring eagerly instantiates singletons), an init-method/destroy-method, #PostConstruct, InitializingBean - afterPropertiesSet() method or return same spring instance in a getInstance() method?
The choice is a tradeoff of testability over reusability outside the spring container.
I recently made a recommendation to one of my colleagues stating that on our current project (C#) "services should be stateless and therefore static".
My colleague agreed and indicated that in our project the services are (and should be) indeed stateless. However my colleague disagreed that static implies no state and that stateless should mean static.
My questions is “does a method marked as static imply that it requires no state and that in a majority of cases should stateless methods be made static”.
Static nearly means global. There is still an instance, and there is still state in that instance, but it is the static instance, which means there is only one and all callers always refer to that one.
does a method marked as static imply
that it requires no state
1) No. You cannot say static methods imply that it requires no state because static methods can access static/singleton resources.
a majority of cases should stateless
methods be made static
2) Yes. Methods that require no state, therefore require no instance, should be generally made static.
A static method, in C#, can access the static variables of its containing class, and if it does, it's not stateless. I've seen some painful instances of non-reentrant "stateless" static methods triggering fun race conditions.
A truly stateless method can indeed be made static, and generally should.
I find it rather scary to say that stateless is the same as static as these are two different worlds. Stateless means that there is no state kept, i.e., a perfect example is an HTTP connection (once data is send, the connection is closed and there's no memory kept), where we are actually trying to do our best to maintain state regardless (login state for one).
Static on the other hand is a term used to describe a way that a method is invoked. In C# that means that a method can be invoked without a class instance, but an instance of a class is not the same as state. There's still the static instance and that's perfectly capable of maintaining state: any static member variable, field or property can maintain state. A static method or class is also perfectly capable of maintaining state by using memory mapped files, a database or whatever. Static is a calling convention, nothing more and is not related to being stateless or not.
I think his statement makes about as much sense as "Democracies should use yellow paper ballots".
He is mixing a high level design concepts "stateless services" with a low level technical implementation detail "using static classes".
Stateless services can (and have been) implemented in languages which supports only static variables (e.g. COBOL, RPG) and languages which dont even allow static variables (Erlang etc.).
I could easily imagine a case where stateless service was implemented largly using static classes, becuase they were there and already implemented the correct business logic, although its generally considered good Java programing practice not to use static classes unless you really need to.
He also serioulsy misunderstands what "static" is all about -- a static variable is a way of storing state between invocations -- and would therefore seem a better match with a "stateful" service.
static is a language keyword and state is a design concept. There's an obvious relationship between these two things, but it is a relationship of the concrete to the metaphysical, not a relationship of cause and effect. It is possible for static methods to refernce some kinds of state information.
Regarding stateless methods, here we are talking about method that don't reference a class instance, i.e. a this pointer. Marking these methods as static improves the clarity of the code and is consistent with best practices. Note that in this case we are talking a specific kind of "statelessness" and not making a general commentary about the use of stateful contexts.
static can be stateful. you just have to define static containers for said state. and the containers are shared among all calls to your static methods.
The short answer to your question is "no", static does not imply "no state".
In reference to your other comments, static can be used to help you implement a stateless service, but static alone is not sufficient. Another tool/technique to help make something stateless is to use immutable data structures. This (currently) isn't one of C#'s fortes, especially when compared to F#.
Beyond rehashing all the definitions of "static" that one can run through, the answer is "yes." Static methods may happily modify the state of the Class itself (represented through static variables), and even modify the state of instances of the class (notably, when they get passed an instance or set of instances). However, most of the time, you will use static methods in cases where no state is changed. The most important example is to find or create an instance (factory methods).
That said, the real answer is "no." In real life (Web Services over HTTP, for instance, or interaction with any kind of Orb), services never expose their service methods using actual static methods. You usually call static methods to get an instance of the service (or an instance of the service factory, from which you get an instance!), and then work with that. This is because your service proxy, internally, needs to keep track of where it's at. So while your methods seem stateless to you, they are really not.
Hope this wasn't too confusing :)
A Static class is not stateless. It can still have variables which, although static, have a state.
A Static class without any class-level variables is stateless. It holds no data.
Every class has a class definition structure, where static fields are represented and stored. Every "instance" of the class has access to the static fields stored in the class definition (a data structure caleld CORINFO_CLASS_STRUCT). Even when NO instances have been created, code anywhere in your assembly can access these static class-level fields by using the syntax classname.StaticFieldName, without any instance at all.
Since the values stored in these static class-level fields are persisted, they are definitely state. In fact, they are state shared by not only any instances of the class that might exist, they are shared throughout the assembly, whether any instances have been created or not.
Even more significant, since once a CORINFO_CLASS_STRUCT class definition has been loaded, unlike a true instance of the class, it is never unloaded until the assembly (or the AppDomain) is unloaded, so it is arguably more stateful than any instance field defined in a class, because an instance field dissapears when the instance gets garbage collected.
For more information check out CORINFO_CLASS_STRUCT link to Don Boxes' great book, Essential .Net
That is generally correct. However you can have static variables, which allow your static methods to have state. For instance, take this FooBarFactory class:
class FooBarFactory
{
private static _id = 0;
public FooBar MakeAFooBar()
{
FooBar foo = new FooBar();
foo.ID = _id;
_id++;
}
}
class FooBar
{
public int ID {get;set;}
}
In that case your static method has a minimum of state, but it's (probably) neccessary.
If you want a single instance with state, use a singleton pattern; it makes the intent clear that you're working with a single-occurrence object.
From that, I would then treat all static classes and methods as stateless. It just helps keep sanity.