-2

There are three Object Oriented relationship types i.e. Aggregation, Composition and association as described here: What is the difference between association, aggregation and composition?.

IOCs support composition by allowing you to do this:

public class MyClass
{

MyClass2 MyClass2;

public MyClass(MyClass2 myClass2)
{
  MyClass2 = myClass2;
}
}

I believe the code above is an example of Aggregation as MyClass is not responsible for the lifecycle of MyClass2.

Here is an example of Association i.e. MyClass2 is passed to the method (instead of being injected into the class):

public void MyMethod(MyClass2 myClass2)
{
   //Do something
}

I can do something like this for Composition:

public class MyClass
{

WindsorContainer Container;

    MyClass2 MyClass2;

    public MyClass(WindsorContainer container)
    {
      Container=container;
      MyClass2 = Container.Resolve<MyClass2>();
    }
    }

However, I believe the Composition example uses the Service Locator anti pattern. How do I use composition without using the Service Locator pattern?

w0051977
  • 15,099
  • 32
  • 152
  • 329
  • 1
    You can pass factory for example. `public MyClass(Func class2Func) { MyClass = class2Func();}` – Evk Nov 08 '17 at 12:01
  • @Evk, do you mean inject a factory into the class and then use the factory to create an instance of the class? – w0051977 Nov 08 '17 at 12:16
  • Yes, just like I did (I think) in my small code example above. For some containers you need to create special factory classes and some containers allow to inject `Func` directly, without special factory classes. With that it's still clear your class has dependency on SomeClass, unlike when you use container directly. – Evk Nov 08 '17 at 12:16
  • Possible duplicate of [Func injecting with Windsor container](https://stackoverflow.com/questions/2600277/funct-injecting-with-windsor-container) – mjwills Nov 08 '17 at 12:22
  • @mjwills, could you explain how that is a duplicate? – w0051977 Nov 08 '17 at 13:52
  • It seems you are asking how to avoid using `MyClass2 = Container.Resolve();` If you register as shown in that answer then you should be able to use `public MyClass(Func myClass2)` and then create them as needed. Apologies if I have made a mistake or misunderstood. – mjwills Nov 08 '17 at 20:06

1 Answers1

1

If you find yourself using the Service Locator Pattern you are correct to question it, but it has it's place and is OK to use if you need to.

One thing that you may be slightly off on is how IoC injects. IoC can do constructor, property and method injection, so your association example can still be dependency injection.

Composition without IoC is fine if the object doesn't provide any real logic. If what you want to compose into your class is just a DTO, then you don't need to inject it anyway.

Crowcoder
  • 11,250
  • 3
  • 36
  • 45
  • Can you provide an example of composition with ioc? – w0051977 Nov 08 '17 at 12:15
  • If you need to compose by injection then take the item as a dependency in a method, property or constructor. Anything else you might do could just be a hack. Like, some containers support interception which allows you to inject code at runtime (AOP) but that's just overkill when you can inject. Again, if your type doesn't have any behavior that uses external dependencies then you can just compose without DI. Think about your variables of type int, string, Stream, etc, you don't inject those because you don't need to. – Crowcoder Nov 08 '17 at 13:24