In response to my question here that was half way about having a circular dependency:
C# ASP.NET Dependency Injection with IoC Container Complications
The presenter depends on an IView. And the Page (implementing the IView) depends on a presenter. Other have solved this converting from constructor injection to property injection
I didnt like this because I felt that you now need to make public properties that can be modified externally, and also becomes the developers responsibilityies to initialise.
But it seems that I have been able to solve this another way.
By the page having a default constructor as well as an overloaded parameterised constructor, you can via reflection call the parameterless constructor to create the object
then call the overloaded one by injecting the dependencies.
I’ill illustrate by example:
class TestObject
{
public string Name { get; set; }
public TestObject()
{
Name = "Constructed with no args";
Console.WriteLine("constructor hash code: " + GetHashCode());
}
public TestObject(string name)
{
this.Name = name;
Console.WriteLine("constructor hash code: " + GetHashCode());
}
}
This object can be constructed simply:
var obj = Activator.CreateInstance<TestObject>();
or
var obj = new TestObject();
But then I can via reflection use the overloaded constructor to inject the dependencies:
ConstructorInfo ctor = obj.GetType().GetConstructors()[1];
ctor.Invoke(obj, new[] { "injected" });
I was able to use this approach to wire up structuremap to register the instance after creation and then inject the dependencies.
Of course we can use a regular method to inject the dependencies, but this again breaks the encapsulation a bit, so you could call this
again to override dependencies.
Also as constructor this cant simply be reached by static code.
But I have no idea how I feel about this, it feels a little bit like a hack or something that i can simply do accidentally in C#.
I would like to hear your thoughts
Thanks.
I don’t like this use of reflection as it means you can’t easily create a view/presenter with out a an IoC container.
One way of solving the need for an IoC container is to use a factory to easily create a view/presenter and placing the reflection logic in the factory.
However, at this point you could have a simple property or
Initialize(view)/Initialize(presenter)method. The responsibility for calling these methods is taken away from the developers by the factory or the IoC container (which is acting as a factory).An alternative to passing the dependency to the object when constructing is to pass an factory that can build the dependency to the object. The simplest form of factory is a simple
Func.If you do insist upon having a pair of constructors I would make the no argument constructor protected unless it really is valid to create the view/presenter without a presenter/view. This would prevent someone using that constructor by mistake, since there’s no way without reflection to initialize the view/presenter after construction.
Though I then think this is a slightly better on the reflection idea would be to make a parameterless constructor that is protected, and a protected initialize method.
This enforces that you can’t construct it without a name, unless you use reflection. The reflection would be encapsulated in a factory which would ensure
Initializeis also called.