1

I'm currently trying to implement a simple dependency injection container that uses XML to define the class dependencies. The questions I have are mainly related to design.

Here is an example XML schema that I am thinking about using:

<?xml version="1.0">
<classes>
    <class name="MySQLDatabase">
        <namespace>MyLib\Database\</namespace>
        <dependency type="constant">my_db_username</dependency>
        <dependency type="constant">my_db_password</dependency>
        <dependency type="constant">my_db_database</dependency>
    </class>
        <class name="LoginManager">
        <namespace>MyLib\Authentication\</namespace>
        <dependency type="class">MySQLDatabase</dependency>
    </classes>
</classes>

My first question is, does anyone foresee any problems with a schema similar to the above?

My second question is, how should I go about translating this into an my definitions array? This question isn't about how to parse the XML, rather the design of the array that will hold the information once parsed.

If I was coding this in Java, I was thinking of something like this, but I'm not sure if this is too bulky and how this would translate into PHP, which doesn't seem to have the same amount of data structures as Java does.

class DIClass {

    public HashMap<String, ClassDefinition> definitions;

    // example
    // definitions = map of the classes below
    // ...
}

class ClassDefinition {

    private String name;
    private String namespace;
    private List<Dependency> dependencies;

    // example
    // name = MySQLDatabase
    // namespace = MyLib\Database\
    // dependencies = list of the class below, ordered
    // ...
}

class Dependency {

    private String name;
    private String type;

    // example
    // name = my_db_username
    // type = constant
    // ...
}

My last question is, what about adding a definition for persistence? For example, the database class should be a singleton. Should I just add an extra <persis /> tag into the class definition in the XML file?

Thanks for looking.

Mick
  • 665
  • 2
  • 6
  • 18
  • You need some kind a indication of how the dependency will be injected (constructor or setter) or even if a object is created via a new call or factory method call. – Orangepill Jun 12 '13 at 03:41
  • Hi Orangepill, thanks for the comment. The dependency will be injected via the constructor, and the object created via the DIClass (similar to how a factory does it). I was going to edit my code to reflect this, but I got stuck. I was under the impression that PHP's eval(), or something similar would be able to parse a function string with parameters, in which I would loop through my dependency list and "create" the function (string) by adding the dependencies in as parameters in my factory, but this doesn't seem to be the case. – Mick Jun 12 '13 at 04:07
  • 1
    instead of eval you might want to look at the ReflectionClass::newInstanceArgs as a means to create a new object from a string definition – Orangepill Jun 12 '13 at 04:16
  • Thanks Orangepill, that's exactly what I need for the implementation part of this :) – Mick Jun 12 '13 at 05:23
  • if you decide to allow static instantiation (singleton, abstract factory) then you can use call_user_func_array with an array as the first parameter. I would also advise that you create the container flexible enough to support other creation patterns/injection methods than constructor injection if for no other reason than to allow your container to manage third party classes. Another feature that I have seen in other php di implementations and I thought might be useful is the concept of designating a shared instance for some types. – Orangepill Jun 12 '13 at 05:38
  • That might be verging over into the service locator realm though... I'm still a little fuzzy on where the line between the two is. – Orangepill Jun 12 '13 at 05:39

1 Answers1

2

My first question is, does anyone foresee any problems with a schema similar to the above?

You are re-inventing the wheel. PHP is a scripting language, so instead of an XML file you can as well just use a PHP file - it's much more expressive for - well - PHP :)

My second question is, how should I go about translating this into an my definitions array? This question isn't about how to parse the XML, rather the design of the array that will hold the information once parsed.

You can do that by mocking with an array first and then thinking backwards, like how to store the information you have in the array into an XML file - or just drop the XML completely and just load the array (see the point above).

My last question is, what about adding a definition for persistence? For example, the database class should be a singleton. Should I just add an extra tag into the class definition in the XML file?

If you need them a singleton, instantiate them once and that's it. You don't need singleton persistence in PHP normally. That's a large misconception (if you come from a Java background this gives a good insight: Singletons have very little - if not to say no - use in PHP (a must read)).

See as well the following realted question(s):

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836