Is non-trivial constructor in IoC paradigm a bad thing? - c#

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.

Related

.NET: Determine whether object is partially or fully constructed

Is there any way to query the .NET runtime to determine whether an object has finished its construction, or if the construction is still on-going and/or was aborted with an exception?
Basically, something equivalent to:
class Foo {
public string ConstructionState { get; private set; }
public Foo() {
try {
ConstructionState = "ongoing";
// ... do actual constructor stuff here ...
ConstructionState = "completed";
}
catch (Exception) {
ConstructionState = "aborted";
throw;
}
}
}
... except also taking into account field initializers, base class constructors etc., and without needing to modify the constructor.
A well-behaved object should never expose itself until it's fully constructed. If a partially constructed object is leaked, you're already violating that contract.
The runtime doesn't care, of course. There's nothing special about a partially-constructed object as far as the runtime is concerned - it's still subject to the same memory constraints, finalization and garbage collection as a fully constructed object.
If you own the object, the solution is simple - don't leak the object during construction. The usual way to do some global change during object initialisation is to use a static method (or a factory) instead of a constructor. If you don't own the object, you're pretty much out of luck.
The runtime specification doesn't explicitly say there's no way to check if an object is partially constructed, but it doesn't say there is either (as far as I can tell) - so even if you found some way, it wouldn't be safe to rely on it. Inspecting by hand shows that .NET object headers have no such information, and a disassembly of the constructor shows there's no non-user code after a constructor finishes that could update such a state.
The runtime does store a few flags in "weird" places. The mark & sweep garbage collector in desktop MS.NET stores its marks in an "unused" bit of the pointer to the virtual method table, for example. But as far as the runtime is concerned, the object is "done" even before any of its constructors run - all of that is handled during the allocation in newobj, before the constructor (a special instance method) runs. The object header (which also contains the object size) and virtual method table (so the object is of the most derived type even before the constructors run) are already set here, and all the memory directly used by that instance is already allocated (and pre-zeroed - so you don't get pointers to random bits of memory). This means that memory safety isn't impacted by partially-constructed objects as far as the runtime is concerned.
The main difference between a constructor and another instance method is that the constructor must only ever be called once on any instance. On the CIL level, this is enforced simply by the fact that you can't invoke the constructor directly - you only ever use newobj, which pushes the constructed object on the stack. Just like with other instance methods, it doesn't track if a particular method finishes or not - after all, it's perfectly legal to have a method that never finishes, and you can actually do the same thing with a (non-static) constructor.
If you want a proof that the runtime doesn't care, I present to you... the object can be collected by the GC before the constructor even finishes:
class Test
{
public static WeakReference<Test> someInstance;
public static void AliveTest()
{
Test t;
if (someInstance == null) Console.WriteLine("Null");
else Console.WriteLine(someInstance.TryGetTarget(out t));
}
public Test()
{
someInstance = new WeakReference<Test>(this);
AliveTest();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
AliveTest();
}
}
class Program
{
static void Main(string[] args)
{
Test t = new Test();
Test.AliveTest();
Console.ReadLine();
}
}
This test program writes out True, False, False (make sure to run it in Release mode and without the debugger - .NET prevents many things like this to make debugging easier). The object has been collected before its constructor even finished, which means that there's no special treatment for constructors in this regard. Another reason not to use the "constructor updates something static" pattern, and especially not the "finalizer updates it back". If you add a finalizer to this sample code, it will run before the constructor finishes. Ouch.
Even your solution would be insufficient in the general case. To cite CLI specification:
It is explicitly not a requirement that a conforming implementation of the CLI guarantee that all state updates performed within a constructor be uniformly visible before the constructor completes.
There's no guarantee another thread would have correct information about the construction state.
For bonus points, it also doesn't help if the object isn't sealed. A derived classes constructor would run after the base class constructor and in C# there's no way to rewrite this to encompass all the constructors that normally run in a sequence. The best you could do is maintain a separate "constructed state" for each constructor, which is confusing at best (and breaks a few OOP principles - it would require all consumers of the object to know of all possible types the object could have).

Automatically calling method after code block

I'm adding the notion of actions that are repeatable after a set time interval in my game.
I have a class that manages whether a given action can be performed.
Callers query whether they can perform the action by calling CanDoAction, then if so, perform the action and record that they've done the action with MarkActionDone.
if (WorldManager.CanDoAction(playerControlComponent.CreateBulletActionId))
{
// Do the action
WorldManager.MarkActionDone(playerControlComponent.CreateBulletActionId);
}
Obviously this could be error prone, as you could forget to call MarkActionDone, or possibly you could forget to call CanDoAction to check.
Ideally I want to keep a similar interface, not having to pass around Action's or anything like that as I'm running on the Xbox and would prefer to avoid passing actions around and invoking them. Particularly as there would have to be a lot of closures involved as the actions are typically dependent on surrounding code.
I was thinking of somehow (ab)using the IDisposeable interface, as that would ensure the MarkActionDone could be called at the end, however i don't think i can skip the using block if CanDoAction would be false.
Any ideas?
My preferred approach would be to keep this logic as an implementation detail of WorldManager (since that defines the rules about whether an action can be performed), using a delegate pattern:
public class WorldManager
{
public bool TryDoAction(ActionId actionId, Action action)
{
if (!this.CanDoAction(actionId)) return false;
try
{
action();
return true;
}
finally
{
this.MarkActionDone(actionId);
}
}
private bool CanDoAction(ActionId actionId) { ... }
private void MarkActionDone(ActionId actionId) { ... }
}
This seems to fit best with SOLID principals, since it avoids any other class having to 'know' about the 'CanDoAction', 'MarkActionDone' implementation detail of WorldManager.
Update
Using an AOP framework, such as PostSharp, may be a good choice to ensure this aspect is added to all necessary code blocks in a clean manner.
If you want to minimize GC pressure, I would suggest using interfaces rather than delegates. If you use IDisposable, you can't avoid having Dispose called, but you could have the IDisposable implementation use a flag to indicate that the Dispose method shouldn't do anything. Beyond the fact that delegates have some built-in language support, there isn't really anything they can do that interfaces cannot, but interfaces offer two advantages over delegates:
Using a delegate which is bound to some data will generally require creating a heap object for the data and a second for the delegate itself. Interfaces don't require that second heap instance.
In circumstances where one can use generic types which are constrained to an interface, instead of using interface types directly, one may be able to avoid creating any heap instances, as explained below (since back-tick formatting doesn't work in list items). A struct that combines a delegate to a static method along with data to be consumed by that method can behave much like a delegate, without requiring a heap allocation.
One caveat with the second approach: Although avoiding GC pressure is a good thing, the second approach may end up creating a very large number of types at run-time. The number of types created will in most cases be bounded, but there are circumstances where it could increase without bound. I'm not sure if there would any convenient way to determine the full set of types that could be produced by a program in cases where static analysis would be sufficient (in the general case, where static analysis does not suffice, determining whether any particular run-time type would get produced would be equivalent to the Halting Problem, but just as many programs can in practice be statically determined to always halt or never halt, I would expect that in practice one could often identify a closed set of types that a program could produce at run-time).
Edit
The formatting in point #2 above was messed up. Here's the explanation, cleaned up.
Define a type ConditionalCleaner<T> : IDisposable, which holds an instance of T and an Action<T> (both supplied in the constructor--probably with the Action<T> as the first parameter). In the IDisposable.Dispose() method, if the Action<T> is non-null, invoke it on the T. In a SkipDispose() method, null out the Action<T>. For convenience, you may want to also define ConditionalCleaner<T,U>: IDisposable similarly (perhaps three- and four-argument versions as well), and you may want to define a static class ConditionalCleaner with generic Create<T>, Create<T,U>, etc. methods (so one could say e.g. using (var cc = ConditionalCleaner.Create(Console.WriteLine, "ABCDEF") {...} or ConditionalCleaner.Create((x) => {Console.WriteLine(x);}, "ABCDEF") to have the indicated action performed when the using block exits. The biggest requirement if one uses a Lambda expression is to ensure that the lambda expression doesn't close over any local variables or parameters from the calling function; anything the calling function wants to pass to the lambda expression must be an explicit parameter thereof. Otherwise the system will define a class object to hold any closed-over variables, as well as a new delegate pointing to it.

does final static automatically employ lazy instantiation?

the page at http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html?page=5 says that code like this:
public final static Singleton INSTANCE = new Singleton();
automatically employs lazy instantiation.
I want to verify if
1) all compilers do this, or is it that the compiler is free to do whatever it wishes to
2) and since c# does not have the "final" keyword, what's the best way to translate this into c# (and at the same time it should automatically employ lazy instantiation too)
Yes. The static initializer is guaranteed to run before you are able to access that INSTANCE. There are two negatives with this approach:
If an error occurs within the Singleton's construction, then the error is a little harder to debug ("Error in initializer").
On first use of the class, that object will be instantiated. If you did the locking approach, then it would not be instantiated until it was needed. However, being that the example is a singleton, then this is not a problem at all, but it could be a drag on an unused, yet lazily instantiated piece of code elsewhere that is not a singleton.
The translation for C# is readonly instead of final.
In my opinion, this is still vastly preferable to the secondary approach (synchronized/locked, checked instantiation within the a static getter) because it does not require any synchronization code, which is faster, easier to read and just as easy to use.

lazy initialization of singletons

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.

In an IDisposable pattern should a base class allow derived classes to share its disposed flag?

I am currently working on fixing a c# codebase which does not have a good pattern of Dispose usage.
It is a large codebase, it is a resource demanding codebase and it uses many custom unmanaged c++ libraries at the low level.
I have a good understanding of the dispose pattern. I have spent some time understanding what I believe to be the gold standard article on the issue: Joe Duffy's dispose article
In an attempt to minimise code duplication, we have been considering some dispose helper classes, and so my question:
If a base class implements a standard Dispose pattern should it allow its disposed flag to be shared ie. marked as protected?
To clarify I mean should there only be a single boolean state within an inheritance heirarchy that defines whether an object instance has been disposed or should there be a private boolean at each step of the inheritance ladder?
The examples in MSDN and at the above link set a flag at each level, but never explain the reasoning behind it. I am in two minds on the issue, what are your thoughts and reasons?
I would say no it should not share the flag. Sharing the flag creates opportunities for failure which better encapsulation could prevent.
For instance, consider the scenario where you have a readonly Disposed property on the base most class. The backing field is only set to true in the Dispose(disposing) method on the base class. This means that the property Disposed can only ever return true if the base class Dispose is called (barring evil reflection of course). This allows the base class to provide an enforceable contract.
Now consider the opposite, where there is a protected setter. Any class can now arbitrarily set the Disposed property to true without disposing anything. This creates an opportunity for Dispose to return true when nothing is disposed.
I would choose the first option because it provides the most enforceable contract.
I would recommend having a Disposed property on the base class with a public getter and a protected setter.
In the case you have methods that should do something different when the class has been disposed, for example throwing an exception, I would create a protected only getter property for the base class that reads the private field on the base class. This way you allow any inheritor to know if he's able to perform an operation.
Then, for knowing if a class has already been disposed into its own dispose method (for example: to avoid releasing resources twice), I think that having a private flag is better for clarity and maintenance.
In addition to JaredPar's answer, I'd add that it is not always necessary for there to be a _disposed flag. Very often, the other "resource-related" fields of the object naturally provide a way to represent the disposed state.
For example, an external COM object that needs to be Shutdown before it is discarded would be represented by a reference to the COM object, and so the relevant part of Dispose would be:
if (_comObject != null)
{
_comObject.Shutdown();
_comObject = null;
}
This can safely be run multiple times without calling Shutdown more than once, as is required. Other methods that attempt to use _comObject after Dispose will get a NullReferenceException, or ideally those methods would check the _comObject field and throw ObjectDisposedException.
I find this is more often true than not - having frequently implemented IDisposable, I can't recall ever needing a separate _disposed field. Introducing one would increase the degrees of freedom (increase the number of ways for me to screw it up).
So this is unlikely to be that useful for derived classes even if it was a safe idea (which it isn't, as JaredPar explains).

Categories