Instead of injecting the entire DI Container into your classes, you should inject only the dependencies you need Your UserController requires a DB Adapter (let's call this interface IDBAdapter). In C# this might look like this: public class UserController { private readonly IDBAdapter db; public UserController(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this. Db = db; } public void DetailsAction() { var model = new UserModel(this.
Db); model. GetDetails(12345); } } In this case we are injectiing the dependency into the UserModel. In most cases, however, I would tend to consider it a DI smell if the UserController only takes a dependency to pass it on, so a better approach might be for the UserController to take a dependency on an Abstract Factory like this one: public interface IUserModelFactory { UserModel Create(); } In this variation, the UserController might look like this: public class UserController { private readonly IUserModelFactory factory; public UserController(IUserModelFactory factory) { if (factory == null) { throw new ArgumentNullException("factory"); } this.
Factory = factory; } public void DetailsAction() { var model = this.factory.Create(); model. GetDetails(12345); } } and you could define a concrete UserModelFactory that takes a dependency on IDBAdapter: public class UserModelFactory : IUserModelFactory { private readonly IDBAdapter db; public UserModelFactory(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this. Db = db; } public UserModel Create() { return new UserModel(this.
Db); } } This gives you better separation of concerns If you need more than one dependency, you just inject them through the constructor. When you start to get too many, it's a sign that you are violating the Single Responsibility Principle and it's time to refactor to Aggregate Services.
Instead of injecting the entire DI Container into your classes, you should inject only the dependencies you need. Your UserController requires a DB Adapter (let's call this interface IDBAdapter). In C# this might look like this: public class UserController { private readonly IDBAdapter db; public UserController(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this.
Db = db; } public void DetailsAction() { var model = new UserModel(this. Db); model. GetDetails(12345); } } In this case we are injectiing the dependency into the UserModel.In most cases, however, I would tend to consider it a DI smell if the UserController only takes a dependency to pass it on, so a better approach might be for the UserController to take a dependency on an Abstract Factory like this one: public interface IUserModelFactory { UserModel Create(); } In this variation, the UserController might look like this: public class UserController { private readonly IUserModelFactory factory; public UserController(IUserModelFactory factory) { if (factory == null) { throw new ArgumentNullException("factory"); } this.
Factory = factory; } public void DetailsAction() { var model = this.factory.Create(); model. GetDetails(12345); } } and you could define a concrete UserModelFactory that takes a dependency on IDBAdapter: public class UserModelFactory : IUserModelFactory { private readonly IDBAdapter db; public UserModelFactory(IDBAdapter db) { if (db == null) { throw new ArgumentNullException("db"); } this. Db = db; } public UserModel Create() { return new UserModel(this.
Db); } } This gives you better separation of concerns. If you need more than one dependency, you just inject them through the constructor. When you start to get too many, it's a sign that you are violating the Single Responsibility Principle, and it's time to refactor to Aggregate Services.
Mark Seemann, thank your for your anwer! I will read it some times to understand the advantages. – Kirzilla Mar 10 '10 at 9:57 I see the only disadvantage of your method (imho).
What if I'm calling UserModel method which don't need any connection to DB? All Dependency Injection Objects passed to UserModel constructor are already being created in UserModelFactory. (This all is about performance).
What do you think of this realization of DIContainer? Twittee. Org – Kirzilla Mar 10 '10 at 10:08 If the UserModel doesn't use the DB in all cases you might want to consider whether it should take a dependency on it at all.In any case, you don't solve any issues by injecting the container instead of specific dependencies, and I generally don't buy the argument about performance, because expensive services (like the DB adapter) tend to be shared amongst many consumers, and even if this isn't the case, there are ways to deal with that: blog.ploeh.
Dk/2010/01/20/… – Mark Seemann Mar 10 '10 at 10:23 Thank you so much! – Kirzilla Mar 10 '10 at 14:01 By the way, using your method I can encapsulate any DIContainer Objects.It is impossible to do if I will inject whole DIContainer. Thank you!
– Kirzilla Mar 10 '10 at 14:07.
I'd use a singleton object for all config parameters : You set it up in your bootstrap, then choose to use it directly or pass it as parameter in your objects. The idea being to have one method all around to retrieve your config data. You may then provide an abstract class for db manipulation which uses your config.Singleton.
DependancyInjection can still be used to override your default data. The above link in the comment (possible 'duplicate') concludes on using constructor injection : this is close to your current method. However if I try to figure how your model works, I guess you will have many other model classes other than "userModel".
Thus an abstract class using a config singleton might be a good solution : all your next model classes will just extend this abstract class, and you don't have to worry about your config. On the other hand, your solution is good to me as long as your dependanceInjectionContainer changes often.
Frankly speaking, objects in my dependanceInjectionContainer are not changing often. I'm storing DB Adapter, Memcache Adapter, Mail Adapter and Config in dependanceInjectionContainer. So, probably, some kind of Registry is ok for me.
I can't even imagine situation when I should change anything in dependanceInjectionContainer (any real life situation samles? ) – Kirzilla Mar 9 '10 at 13:07 As far as my humble experience can speak, I have not yet seen any use of DI for a controller. Maybe if you need to juggle with multiple databases?
Or if you pass some user specific parameters (providing a theme for exemple) – Rodolphe Mar 9 '10 at 13:17 By the way, I can make dependanceInjectionContainer a Singleton and get it's instance in Controller or Model. It will help me to avoid passing dependanceInjectionContainer into constructor. So, let's wait for Mr. Mark Seemann answer to see what is the key.... – Kirzilla Mar 9 '10 at 13:20 Yeah, I'm dealing with multiple databases and memcaches, but I don't think that it changes anything.
I can keep DB_1 Adapter & DB_2 Adapter in dependanceInjectionContainer as well as I can keep it in Registry singleton. – Kirzilla Mar 9 '10 at 13:22 Just found pretty nice article about Dependency Injection in ZendFramework developertutorials. Com/tutorials/php/… – Kirzilla Mar 9 '10 at 13:27.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.