문제

I know there is a similar question Here But I think mine expands on this a bit more.

I have recently been working on an Application that has been in production for about a year, with no issues and no real plan for extension. The application had few dependencies and used DI but without a container.

Now I am extending the application to a much broader scope at the company's instruction, this led me to implement the use of an IoC Container. The issue here has been the overhead of adding a container to code I previously thought would not ever require one.

My specific question as I move forward is:

  1. When planning and coding smaller applications that presumably will not expand much, should I implement a container in anticipation that scenarios such as these may present themselves and in such anticipation I would be better off implementing a container from the start so upon extension the framework already exists.

  2. Is it a sign of poor design if implementing a container when extending an application beyond its original intention becomes cumbersome?

EDIT:

I am using solid principles (to the best of my ability) and interfaces extensively in my applications currently, the question is more related to the use of an IoC Container, not DI in and of itself. The application mentioned before is a roll-your-own DI style that I am adding a container to which is where the question arose.

도움이 되었습니까?

해결책

I'm a big fan of Clean Code and especially YAGNI. "You ain't gonna need it". If you don't need DI in a project, don't use it. If you need DI for Unit tests but don't need a container, don't use one. Simplicity is a virtue of it's own. Keep it as simple as possible.

If preparing a project for future extensibility costs time or money now, don't do it. You can pay that in the future. Because that future may never come. And if it does, it certainly will not be as predicted and your preparation will be not as useful as you thought.

I've been in projects where there was so much "extensibility" code, that you could have deleted at least 75% of the source code and all required functionality would still have been there. I have no problem envisioning the project manager wondering what the hell took so long to implement such a basic functionality. Don't do that. Plan your project, get your requirements and implement them. If extensibility is a requirement, plan it, estimate it, let your managers know. My guess is they don't want extensibility that badly. They'd rather have another working program instead.

That said, obviously you are learning. If it doesn't cost anything in terms of time or money, go ahead and develop your next program so it can more easily be extended. Just keep an eye on the cost.

다른 팁

  1. I think using DI can be benificial in even the smallest of applications and there are very few disadvantages (the overhead is really minimal). Using a container is probably always faster than rolling your own (not to mention stabler)

  2. Ideally, if you applied solid principles and are programming against interfaces, instead of concrete types, you should only have to modify the composition root. That implies of course that you have been using DI without a container and had a DIY-solution. If not, then probably it will be a bit more difficult to move to DI.

I would recommend not tackling the whole refactoring at once. Do it step-by-step in small increments and test as you go. That has the highest chance of not breaking any existing functionality and it will allow you to catch mistakes in the overall design of the application

1. When planning and coding smaller applications that presumably will not expand much, should I implement a container in anticipation that scenarios such as these may present themselves and in such anticipation I would be better off implementing a container from the start so upon extension the framework already exists.

Why not position yourself for future success? The benefits are numerous, even in a small app, and the additional work is minimal.

2. Is it a sign of poor design if implementing a container when extending an application beyond its original intention becomes cumbersome?

Some may argue that the design was initially poor by not using a container. You'll probably be improving the design, so that can't be a bad thing if done correctly. What was the original intention? To be tightly-coupled and difficult to test? I say, go forward with your idea.

BTW, If your not making gratuitous use of interfaces, currently, I suggest this is a good time to start.

Comparing manual injection and automatic injection:

1)

As mentioned in another answer, using a container from the start for future proofing your solution is a good idea in my opinion. However, I strongly recommend following up this with a good coding standards document. To show the need of this, check out the following code which I have seen in a production system.

public class MyClass
{
 IUnityContainer _container;
 public MyClass(IMyDependentInterface dpenedentclass, IUnityContainer container)
 {
 _container = container;
 //........
 }

 public void DoSomething()
 {
  var obj = _container.Resolve<ISomeOtherInterface>();
  obj.DoAction();    
 }    
}

Unknowingly there is an anti pattern established here(service locator?). As you can see, there is no fail proof design in this world it seems. So don't hesitate to add seemingly obvious content in your coding standards document.

2)

If moving to automatic injection is difficult, it is a sign of something bad. It could be design, but never underestimate the power of poor implementation spoiling design as explained in the previous point.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top