mercredi 15 décembre 2021

Assign class fields with reflection BEFORE construction of the instance

I want to either guarantee that fields used in the constructor are populated before construction, or somehow throw an exception if one of these fields is used in the constructor.

I am writing an injection framework for Unity3D. I have a use-case like this that emerged:

public class TestInjectable : IInjectable
{
     [Inject] TestDependency testDependency;

     int testValue;          

     public TestInjectable()
     {
          testValue = testDependency.value;
          //testValue is NULL here, because testDependency is injected AFTER construction
     }
}

public class TestDependency : IInjectable
{
     public int value = 5;
}

If I go like this, it works jus fine:

public class TestInjectable : IInjectable
{
     TestDependency testDependency;

     int testValue;          

     public TestInjectable(TestDependency testDependency)
     {
          testValue = testDependency.value;
          //testValue is 5 here, because testDependency is injected as a constructor parameter
     }
}

public class TestDependency : IInjectable
{
     public int value = 5;
}

I can use construction-parameter injection to make this work. However, after adding the [Inject] attribute for class fields, the idea of using those fields at construction, without constructor parameters, has entered the mix.

First: It would be nice to make the above work somehow... The created instance is required to set its field values, meaning construction must occur first regardless. I am not sure how to get around needing the constructor to run before injecting the fields.

Second: I would also be fine just throwing an exception for now, alerting the user that using an [Inject] field inside the constructor cannot occur... I was not able to find a solution for detecting if a field is used inside a constructor.

Third: If neither of these can be accomplished, I will have to rely on users reading the documentation, where I can explain this issue. Or, I will have to consider removing the [Inject] feature, which besides for this pit-fall, can be very useful for defining injection.... I would hate to take it out.





Aucun commentaire:

Enregistrer un commentaire