Search code examples
c#oopdesign-patternsconstructorproxy-pattern

Good Constructor Design


In general, is it a bad idea to construct other objects within a constructor (I generally don't like it)? Suppose an object of type A needs an instance of type B. The instance of type B should be static, because I truly only want one copy of it...really...no, seriously. Type b also raises events that type A will need to handle. Type B is in an external library that I have no control over. Making my type B object static seems like it would be an annoyance on testing. I originally wanted to make A completely static, because it is essentially a proxy of B. Maybe that's the real question. What's a good proxy design when the object being proxies requires initialization? I can think of at least three options:

  1. Pass in the arguments need to construct type A along with type B. The constructor of type A then constructs type B. (Calling a create method to return type B from within the constructor would be the same basic concept.
  2. Pass in a constructed object.
  3. Create an initialize method.

I don't like option 1 because it's just complicated. I would have to do all sort of type B initialization code, set up event handlers, etc. I don't like option 2 because I don't want the outside world knowing about this dependency. Class A is the only type that will EVER interact with Class B. In general, I don't like initialize methods, or methods that "guard" the state of an encapsulated dependency. I seem to end up with a lot of code like this:

if (typeB != null && typeB.State != Unitialized)

Yuck.

Here is some sample code that I am working with. Just looking for how to make this really clean, simple and easy to maintain.

public class A
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private B b;

        public new A(string productName, string serviceName)
        {
            b = new B
            {
                ProductName = productName,
                ServiceName = serviceName
            };

            b.SomethingHappened += b_HandleIt;

UPDATE: I referenced this pragmatic article in a comment to an answer. I'm familiar with DI, IoC, Factory Method, Builder Pattern, Constructor Injection, Method Injection, Property Injection, Test Driven Design, etc. I suppose my question is, how do I balance simplicity and good design while coding as little as possible and as quickly as possible against my current needs? Class B will never be replaced and there is no reason for me to believe anything except Class A will ever use Class B in my project. I am somewhat concerned about seams for testing, but class A is very simple, has little code, and basically wraps a third party class.


Solution

  • Ended up going with DI using contructor injection. Wasn't absolutely thrilled, but it seemed to be the most straightforward approach.