4

My goal is to keep my framework as decoupled from my application as possible (though I know it's not entirely possible).

I have several different common types of Models that I use in my application...mappers, data objects, and value objects. For example, UserMapper takes a UserData object and gather info from the database and then maps it into a UserValue object for use within the Controller.

That means that these models have the following dependencies:

  1. UserMapper: needs UserData, and a way to build UserValue(s)
  2. UserData: needs Db (from framework)
  3. UserValue: needs nothing

Do I include in my framework's DIC methods to create Mapper objects, Data object, and Value objects, so that the dependencies could be automatically inject? Or do I create a separate DIC / Factory to handle the Business Layer stuff?

johnnietheblack
  • 13,050
  • 28
  • 95
  • 133
  • 1
    No module can be completely decoupled from the others. After all, a module that operated in total isolation from other modules isn't much use to anyone! What matters is how "tight" the coupling is. DI is a technique that allows coupling between modules to remain loose. Type-hinting a class to be injected is looser than creating/fetching the class in the method itself because you can substitute a subclass of the requested class. Type-hinting an interface is looser still because now you can pass in any object provided it implements the interface. – GordonM Feb 02 '12 at 22:44
  • Related: http://stackoverflow.com/questions/4835046/why-not-use-an-ioc-container-to-resolve-dependencies-for-entities-business-objec/4836790#4836790 – Mark Seemann Feb 03 '12 at 07:38

1 Answers1

0

A dependency injection container could handle the creation of all objects. This includes your DIC using factories to create specific objects that use the factory pattern.

I like to load my DIC up with closures that create the objects. This way all objects are lazy loaded only when requested, but I can still have a lot of flexibility when it comes to object creation.

You could write in a way that your datamapper is given a blank uservalue object, and then initializes the object's data based on DB data. The alternative is to create a tight coupling between your datamapper and uservalue classes by having the one create the other by itself.

Trying to separate you framework from your business logic shouldn't mean not allowing the two to touch, just that no business logic code goes in to your framework's code. using a DIC to create objects that are used for business logic doesn't mean that there is business logic in your DIC.

dqhendricks
  • 19,030
  • 11
  • 50
  • 83
  • Thanks for the answer...so, you are saying then, that my DIC could create framework stuff, like Config, Cache, and Session objects and also business stuff like UserMapper, UserValue, etc? – johnnietheblack Feb 02 '12 at 23:58
  • Depending on how many objects you intend to create I would have a look at the performance of your container. A DI container is not just a factory on steroids. It does a lot of heavy lifting under the hood. For a couple of hundred or thousand objects that is not a problem. But the larger that number gets the more impact the container might have. Some containers track the objects they create in order to be able to dispose a certain part of the resolved object graph. If you have a lot of business objects that might increase memory consumption as well. – Sebastian Weber Feb 03 '12 at 06:54
  • 2
    Am I the only one who chuckled when read "load my DIC up"? :) – johnjohn Feb 08 '12 at 16:37
  • @johnnietheblack might want to catch the Zend webinar about DI and DICs. Pretty complete explanation. Need a log in and I can't link to the exact webinar, but it is on this page and creating an account is free: http://www.zend.com/en/resources/webinars/ – dqhendricks Feb 09 '12 at 23:28