4

I have a factory that creates products. To do this I need an instance of some other class, that has nothing to do with the actual factory. However all Products should of course use the same instance of it, so I provided that instance to the factory which then passes it to every instance of the Product:

public class MyFactory
{
    Product CreateProduct(MyClass dependency) 
    {
        return new Product(dependency);
    }
}

public class Product
{
    internal Product(MyClass dependency) { ... }
    public void DoSomething() { /* use the dependency */ }
}

However it seems weird to me to provide something to my factory it doesn´t need at all but simply passes to its products.

The other alternative that comes to my mind is to provide the dependency where it´s actually needed, this is the DoSomething-method within Product. However this would enable users of my API to provide different instances of MyClass to different products as shown here:

public class Product
{
    public void DoSomething(MyClass dependency) { /* use the dependency */ }
}

...
var dependency1 = new MyClass();
var dependency2 = new MyClass();
myProduct.DoSomething(dependency1);
anotherProduct.DoSomething(dependency2);

The question therefore is: is it okay to provide a dependency to my factory that is actually a dependency for the actual Product?

4
  • 1
    Why do you need the same instance of the dependency? that seems an odd need to me
    – Zalomon
    May 24, 2017 at 7:46
  • E.g. because you want to use allways the same database-connection for all products that are created by the factory. However for another factory you could use another connection. May 24, 2017 at 8:34
  • 2
    If it is a responsibility of MyFactory to create products with the same MyClass instance injected, then MyFactory actually also depends on MyClass. May 24, 2017 at 9:14
  • @BartvanIngenSchenau that makes absolutely sense. Thanks for pointing that out. May 24, 2017 at 9:17

3 Answers 3

4

I did so in a similar scenario: the "products" communicate via the serial port, hence the "factory" had to give the same instance of that serial port (prevent multi-threading issues!) to its products.

In my opinion, the factory should "inject" all the dependencies required by its products into them, thus returning fully functional "products".

2

I assume the scenario you're imagining is this:

public class MyFactory { // preferably this would implement an interface...
    private readonly MyClass _dependency;
    public MyFactory(MyClass dependency) {
        _dependency = dependency;
    }
    public Product CreateProduct() {
        return new Product(_dependency);
    }
}

This is exactly what you should do, at least to the extent that you use a factory class. All that's happening here is you are (manually implementing) function currying. Let's rewrite this a different way.

Func<MyClass, Action<Product>> CreateProduct 
    = (dependency) => () => new Product(dependency);

Now

var factory = new MyFactory(new MyClass());
var product1 = factory.CreateProduct();
var product2 = factory.CreateProduct();

corresponds to

var factory = CreateProduct(new MyClass());
var product1 = factory();
var product2 = factory();

I'm not saying you should write your code the latter way instead of the former (though I'm not saying you shouldn't either). This is just a model to explain what's going on. In a language with objects but not higher order functions, the Factory Pattern is just a manual implementation of a closure. In functional programming no one talks about the Factory Pattern because it's just a not particularly notable special-case of a ubiquitous aspect of functional programming.

-1

I would store a reference to the IoC container in the factory and use that to create products rather than using the new keyword. The benefits of doing this are that neither the factory or the caller need to know about product dependencies anymore. More importantly the dependencies of products and the dependencies of their dependencies can still use the IoC container. The new keyword in factory pattern tends to break use of IoC.

On the otherhand if you don't need this what you have is better as it is simpler. It's not that weird conceptually that if X is needed to create a product, the factory responsible for creating products also knows about X.

4
  • But your Factory does need to know about the IoC container. Your code should never know the IoCC exists.
    – RubberDuck
    May 25, 2017 at 16:18
  • In particular this doesn´t answer the question at all. My question was not on how the factory might create an instance of Product, but how to apply the dependency to that instance. May 25, 2017 at 16:21
  • If the product is created using the IoC container then the dependency is automatically populated May 26, 2017 at 9:05
  • "Your code should never know the IoCC exists." The factory is responsible for creating objects, if it doesn't use the IoC container to do that the created objects will not have their dependencies provided by the IoC container. Unless I am missing an alternative? May 26, 2017 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.