4

Say I have a C# app, which is layered. I want to test the domain layer independently of other layers. Therefore I have created a Domain Layer project with three classes e.g. Person, Order and OrderItem (hypothetical).

I have used Inversion of Control (Castle Windosr) so I also have a whole load of other classes:

PersonFactory
OrderFactory
OrderItemFactory
IPersonFactory
IOrderFactory
IOrderItemFactory
etc

My Visual Studio project looks "polluted" with these classes. What can I do with these classes? I have thought about creating a folder called: Factories. What do you do with these classes that "pollute" the project?

  • Have you looked at alternatives to Castle Windsor? I'm not sure if you have misunderstood how to use it, or if that IOC container just has weird requirements, but needing factories for everything sounds very broken. Take a look at Ninject for example. It certainly doesn't need factories to plumb things together. – David Arno Jun 17 '17 at 17:46
  • Yeah, I think you just don't know how to use the container or Factories correctly. Factories shouldn't need their own interface, unless you're making factory factories or injecting factories. IoC containers are supposed to make your life easier, not harder. – Robert Harvey Jun 17 '17 at 20:25
  • @Robert Harvey I am injecting them so that they can be used to create objects inside an iterator method. – w0051977 Jun 17 '17 at 20:29
  • Are there multiple implementations of each interface, or just one? – Robert Harvey Jun 17 '17 at 20:30
  • @Robert Harvey, one of the interfaces has multiple instances. The other two have parameterized constructors. – w0051977 Jun 17 '17 at 20:36
6

IoC is a very good thing. But factories that have a strictly 1 to 1 relationship with what they make aren't doing you much good.

A factory should make something FOR something. They shouldn't be a brain dead alternative to a constructor. They should allow for good default values without ever forcing anything to ALWAYS have that default value.

You should keep your behavior separate from construction. That doesn't mean you have to keep all construction in an xml document.

Not all of your construction needs to be in factories anyway. Creational patterns come in many flavors. And sometimes it's best to just build what you need in main.

Don't let any IoC-container box you into a corner. If your thinking has been: I need a Person object so I need a PersonFactory you're living in a hell of your own making.

  • Thanks. What are the alternatives to using a factory. Are you saying just use the NEW keyword i.e. completely bypass castle windsor? – w0051977 Jun 17 '17 at 15:51
  • 2
    @w0051977 I am not a C# developer, but doesn't the framework automatically resolve dependencies if possible - i.e. you're asking for a class directly (not an interface with multiple implementations or a class with multiple subclasses)? – Andy Jun 17 '17 at 16:20
3

I'm going to take a rather different tack than CandiedOrange. Before that though, I want to go over some potential other issues. I don't know if any apply to your situation, but I want to cover all bases.

First, not everything needs to be injected. Things (conceptually) without dependencies, particularly value objects and data transfer objects (DTOs) don't need to be injected just like you wouldn't use dependency injection to inject a StringFactory. Second, you don't need a factory if a class's constructor isn't parameterized except for the dependencies. Third, it may be that too many things have dependencies and you should perhaps restructure your code. For example, if your DTOs need to take dependencies to save themselves, maybe that behavior should be moved out of the DTO so that it doesn't require any dependencies. Fourth, as others have mentioned, you can fall into a trap where you are trying to fit things into the DI framework's mold when that's neither necessary nor helpful. Sometimes it's just easier to have code you've written deal with part of the dependency resolution process in main/the "composition root".

Still, even if none of the above situations apply, you can easily find yourself in your situation. Consider an analogy which is not an analogy but exactly what is happening. Let's say you have the following expression using the operations that were added with LINQ (which I got from here after googling "linq example", picking one of the top links, and picking randomly out of the examples on this site):

customers.SelectMany((cust, custIndex) =>
    orders.Where(o => cust.Field("CustomerID") == o.Field("CustomerID"))
          .Select(o => new { CustomerIndex = custIndex + 1, OrderID = o.Field("OrderID") }));

What it does isn't important. What is important is the three lambda functions. Imagine, as would have been the case in C# 1.0, that you had to use the Strategy Pattern and make a class for each of those lambdas. That would be obscene, you wouldn't do it, and to the extent that you were forced to do it, it would definitely "pollute" your project. The Factory Pattern is just the Strategy Pattern applied to object creation. In fact, if you think of, say, the Person constructor as a Func<Dependencies, Parameters, Person>, a basic PersonFactory is just what you get from currying this, i.e. a Func<Dependencies, Func<Parameters, Person>>. What you actually want in a class that needs to create Persons is the Func<Parameters, Person> part, and you want dependency injection to handle the dependencies.

If you weren't using a dependency injection framework at all, and you just manually wired up dependencies in main/the composition root, you could just depend on Func<Parameters, Person> (or rather Func<Parameters, IPerson>) and simply pass an appropriate lambda function during the wiring. However, many DI frameworks make this difficult or impossible. The upshot is that, for this purpose, you are back in the C# 1.0 situation. (This is one of the reasons why I, personally, am not that keen on DI frameworks [not to be confused with DI itself], especially configuration file driven ones.)

It's possible you can eliminate many of the factory classes using the intuition above, but most likely this will be convoluted to fit into the DI framework and thus not worth it. You weren't clear what "pollution" you are actually concerned about: directory pollution, namespace pollution, Intellisense pollution? For the latter two, C#'s namespacing mechanism can adequately handle it. For the former, a directory is a reasonable solution. What approach makes the most sense depends on the directory structure you're using. For example, if each "entity"/"service" has its own directory, then there isn't really an issue. If you have an "Entities" folder, then having a subfolder for the factory interfaces and, perhaps, some or all of the factory implementations seems reasonable.

  • 1
    I'm still didn't find a DI framework that makes my life actually easier. Their concept is usually sound, but they don't compare to a good architecture tailored to the specifics of the project, if you know what are you doing. – T. Sar Jun 18 '17 at 11:19
  • 1
    @TSar I feel the same. I've studied DI for years and explored many containers. The conclusion I've settled on is that DI Frameworks let you move construction into another language (xml, json, whatever). This is useful mostly in that encourages separation of construction and behavior code because now their is a language barrier between them. If you have a wild uncontrolled team of newbie programmers working with you that might be appealing. But I've yet to see a DI framework do much else that can't be done in the native language if you just care enough to do it. – candied_orange Jun 22 '17 at 20:15

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.