patterncsharpMinor
Illumination as a way of instantiating new objects
Viewed 0 times
instantiatingnewilluminationobjectsway
Problem
Basically, what I mean by illumination is having a method create an object where the caller supplies all the dependencies. This allows us to hide our
Yes, a little bit of reflection is involved, but not too much (IMO).
Please tell me what you think of this type (is the intent behind it clear? et alia):
Edit 2: added some ordering to GetConstructors(). So far, it only orders by the number of parameters.
Edit: here is an example of what you can do with an
```
public class MegaBigClass
{
public MegaBigClass(Illuminator illuminator)
{
var a = new A(); // new in a constructor?! Blasphemy!
var b = new B();
var c = new C();
var x = new X();
var y = new Y();
var z = new Z();
// then actually set the
new keyword behind a dependency on an Illuminator, allowing us to much more easily test our code.Yes, a little bit of reflection is involved, but not too much (IMO).
Please tell me what you think of this type (is the intent behind it clear? et alia):
namespace xofz.Illumination
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class Illuminator
{
public virtual T Illumine(params object[] dependencies) where T : class
{
var constructors = new LinkedList(
typeof(T).GetConstructors().OrderByDescending(ci => ci.GetParameters().Length));
var list = new List(dependencies);
foreach (var ctor in constructors)
{
var parameters = ctor.GetParameters();
var valuesNeeded = new List(list.Count);
foreach (var parameter in parameters)
{
for (var i = 0; i (dependencies);
valuesNeeded.Clear();
}
return (T)Activator.CreateInstance(typeof(T), list.ToArray());
}
}
}Edit 2: added some ordering to GetConstructors(). So far, it only orders by the number of parameters.
Edit: here is an example of what you can do with an
Illuminator. Say you have a class that has a lot of dependencies. We can new up all the dependencies of the dependencies, and then actually assign the fields of the class through illuminator.Illumine() calls:```
public class MegaBigClass
{
public MegaBigClass(Illuminator illuminator)
{
var a = new A(); // new in a constructor?! Blasphemy!
var b = new B();
var c = new C();
var x = new X();
var y = new Y();
var z = new Z();
// then actually set the
Solution
I suppose we are talking about DI.
Based on your example, I can not see the advantages of the
If
The logic of the
Well, lets assume we will use the
MSDN - GetConstructors()
The M:System.Type.GetConstructors method does not return constructors in a particular order, such as declaration order. Your code must not depend on the order in which constructors are returned, because that order varies.
-
because that order varies.! Therfore, it is possible that running the code twice, the class creates objects on different ways.
-
Even if the order of the returned constructors will not change (or will be ordered first), what is if the class to be created becomes a new constructor somedays... That means that all the places where the
Conclusion
I would really suggest NOT to use that class! There are excellent frameworks that adress the problems you are tring to solve (e.g. NInject factory extensions for creating factories, Moq for mocking objecs to enable testability ...).
Based on your example, I can not see the advantages of the
Illuminator class. If MegaBigClass depends on AbcComposite and XyzComposite, the right way would be to pass that objects to the constructor. In your case, you have to pass the dependencies of AbcComposite and XyzComposite to MegaBigClass to be able to create the composite objects within that class. However, MegaBigClass should not be responsible for creating that objects.If
MegaBigClass must be able to create the composit objects during runtime, Illuminator serves as something like a "generic factory" (Btw: In that case, I would call it factory so that other developers know what it is). For that case, the Illuminator provides a way to create objects without using new where the concrete creation logic can be changed for testing. The logic of the
Illuminator is (correct me if I am wrong): Search the first constructor from an unordered list that's signature matches to any sub set of the passed arguments.Well, lets assume we will use the
Illuminator that way:- I am not able to define which constructor should be used. If the class to create has a parameterless constructor that is returned first in
.GetConstructors(), the class will be created always by the parameterless constructor.
MSDN - GetConstructors()
The M:System.Type.GetConstructors method does not return constructors in a particular order, such as declaration order. Your code must not depend on the order in which constructors are returned, because that order varies.
-
because that order varies.! Therfore, it is possible that running the code twice, the class creates objects on different ways.
-
Even if the order of the returned constructors will not change (or will be ordered first), what is if the class to be created becomes a new constructor somedays... That means that all the places where the
Illuminator is used, objects may be created using another constructor! That may result in funny bugs ;)Conclusion
I would really suggest NOT to use that class! There are excellent frameworks that adress the problems you are tring to solve (e.g. NInject factory extensions for creating factories, Moq for mocking objecs to enable testability ...).
Context
StackExchange Code Review Q#134124, answer score: 2
Revisions (0)
No revisions yet.