It's correct to have 2 constructors, one for D

2019-05-06 14:56发布

问题:

I have 2 constructor in my class:

public class VuelingCacheWebServices : IVuelingCacheWebService
    {
        public IVuelingCache apiConnector { get; set; }

        public VuelingCacheWebServices(IVuelingCache ApiConnector)
        {
            apiConnector = ApiConnector;
        }

        public VuelingCacheWebServices()
            : this(new VuelingCache())
        { }
    }

As you can see, I have one constructor depending on IVuelingCache and a default constructor that creates an instance to pass to the first constructor. Is it correct? in this way i get rid of the Factory class.

回答1:

This is one way to ensure that you have a valid instance of IVuelingCache - this pattern has a name - poor man's dependency injection.

Some see this as an anti-pattern, as you are hard coding the "default" implementation into your code.



回答2:

No this is not a good Idea, because your class woul become knowledge about the implementation of IVuelingCache ( new VuelingCache() ).



回答3:

There is some debate as to that pattern being a good idea:

http://lostechies.com/chadmyers/2009/07/14/just-say-no-to-poor-man-s-dependency-injection/

In my opinion, if you have a good default that isn't a logically external dependency, then you should provide that default. If your "default" really shouldn't be a default, or would couple pieces that are too far from each other too strongly, then do not use that pattern.

You couple your code by doing this, so really think long and hard about whether it will be used as a convenience default for locally available default implementations, or if you're really just using this as a crutch, and causing inappropriately strong coupled dependencies.

Also, many people advocate using constructor injection only for required dependencies, and using property injection for optional dependencies. When you use the poor-man's DI pattern, you are making an optional (or defaultable) dependency. You might want to consider using property injection for these optional-dependency cases, as that is the pattern many people expect.



回答4:

There are a few problems with your approach:

  1. It makes your code less understandable. Not only is it more code to write, but it is harder to see what dependencies the class takes. When you have one single constructor, it is immediately clear what its dependencies are.
  2. It makes the class depend on concrete instances. This makes it hard to separate abstraction and implementation and could be bad from an architectural point of view.
  3. It forces you to make changes to that class when implementations change, which is bad for maintainability. Say for instance your application uses ICommandHandler<T> interfaces as abstraction to execute business commands and that your class depends on an ICommandHandler<UpdateUserCommand> and points at the concrete UpdateUserCommandHandler. When you later on want to wrap any ICommandHandler<T> inside a DurationLoggingCommandHandler<T>, DeadLockRetryCommandHandler` or what not, you need to go through your complete application to replace all dependencies, while otherwise it is just a matter of rewiring the configuration in the startup path of your application.