IoC, where do you put the container?

I use the windsor in the castle for my favorite project I'm working on. I'm starting to notice that I need to call the IoC container in different places in my code to create new objects. This container dependency simplifies my code.

There are two solutions that I used to solve this problem.

I tried to create abstract factories as wrappers around a container that I could embed in the parts of my application that should create objects. This works, but has some drawbacks, because the lock makes it difficult to add its own container to dependency. So I have to do it manually, this view defeats the whole purpose of the IoC container.

I used the main class applicationcontroller to migrate the IoC container and work as a central factory / repository. It was pretty successful, but this class gets too big and acts like a central god object, almost all other objects refer to it.

Both solutions do their job, but both have their drawbacks. Therefore, I am wondering if other people have the same problem and have found better solutions.




edit The problem is not in object A, which depends on object B. Here I usually use only constructor injection, and everything works. Sometimes I have objects of type A that need to create a variable number of other objects of type B over their lifetime. I am not sure how to do this.

@Blair Conrad: Maintenance problems are not serious so far. I had several classes depending on the container container calling the container. Resolve <>. And I do not want my code to depend on what I consider to be infrastructure. I am still trying, so I noticed that I had to change a lot of code when switching from ninject to lock for this project.

@flowers: Hmm. I like the decision of your fists. It combines what works with both solutions that I tried. I think I was still thinking too much about objects and not enough in interfaces / responsibilities. I tried whole plants, but I would like them to use the container backstage to create objects, and I did not find out how I can make a container a container in a clean way.

+24
oop dependency-injection inversion-of-control castle-windsor
Sep 20 '08 at 22:48
source share
7 answers

The main advantage of Injection Dependency, at least in my applications, is the ability to write code, which is context agnostic. From this point of view, your second solution looks like it really undermines the benefits that DI can give you. If a “god object” provides different interfaces to each class that references it, it may not be too evil. But if you have come this far, I don’t understand why you are not getting to the hoop.

Example: your God object has a getFoo () method and a getBar () method. Object A needs Foo; object B needs a panel. If A just needs one Foo, Foo should be entered directly in A, and A should not know about God at all. But if A needs to continue to create Foos, giving A a reference to God is pretty much inevitable. But you can protect yourself from the harm done by God by narrowing down the type of reference to God. If you force God to implement FooFactory and reference the FooFactory implemented by God, you can still write code in a neutral context. This improves the reusability of the code, and it increases your confidence that a change to God will not cause unexpected side effects. For example, you can be sure when removing getBar () from God that class A will not break.

BUT ... if you still have all of these interfaces, you are probably better off writing specially designed factory classes and combining all of your objects together, the plants included in the container, rather than wrapping the container at all. The container can still set up factories.

+3
Sep 20 '08 at 23:11
source share

Please never use static classes like IoC.Container.Resolve or ContainerFactory.GetContainer!

This makes the code more complex, harder to test, maintain, reuse and read.

Usually, any single component or service has only one single point of injection - this is a constructor (with additional properties). And usually your components or service classes should never know about the existence of such a thing as a container.

If your components really need to have dynamic permission inside (that is, allowing an exception handling policy or name-based workflow), I recommend considering lending to IoC through highly specialized providers

+11
Sep 30 '08 at 9:22
source share
+10
Feb 01 '09 at 8:16
source share

Although I appreciate the explanation of “custom built factories” and even use them myself, it seems like a smell of code in my own projects, because the public interface (small “i”) continues to change using the new factory and / or the new GetX method for each implementation . After reading Jeremy Miller This is the time for IoC Container Detente , I suspect that generics and injecting the container itself is the way to go.

I would wrap Ninject, StructureMap, or Windsor in some IServiceLocator interface, such as the one suggested in Jeremy's article. Then add a factory container that simply returns an IServiceLocator anywhere in your code, even in loops, as you originally suggested.

IServiceLocator container = ContainerFactory.GetContainer(); while( keepLooping ) { IExample example = container.GetInstance<IExample>(); keepLooping = example.DoWork(); } 

The factory container can always return the same value, you can replace the IoC framework, whatever.

+2
Sep 23 '08 at 13:50
source share

As a continuation of @flipdoubt

If you end up using a service locator type pattern, you can check out http://www.codeplex.com/CommonServiceLocator . It has some bindings available for several popular IoC infrastructures (windsor, structuremap) that can be useful.

Good luck.

+1
Oct 12 '08 at 7:07
source share

I would recommend using strongly typed factories in this case, as you mentioned, which are introduced. These plants can wrap the container, but can allow you to go into additional context and perform additional processing. For example, Create on the OrderFactory can take context parameters.

Having static dependencies on a shared service locator is a bad idea as you lose intent and context. When an IoC instantiates, it can provide the right dependencies based on many factors, such as skipping, context, etc., because it has a big picture.

The CommonServiceLocator is not intended for this purpose, although it may be tempting to use it. The main goal of the CommonServiceLocator is applications / frameworks that want to be compatible with the IoC container. However, applications that use only need to call the locator optimally once to create a hierarchy of components and their dependencies. He can never be called again. If we had any way to achieve what we have. In Prism ( http://www.microsoft.com/compositewpf ) we introduced IContainerFacade to create modules. It is a service locator, albeit a low level. In retrospect, we probably had to create a ModuleFactory or something else and use IContianerFacade to get hold of it, and then use these solution modules and directly access the facade. Looking back, 20/20. This is a fairly low level, although it really does not affect things.

In CSL, we struggled with the denomination because it could lead to confusion. In the end, we decided on CSL, because technically the interface was not for you to make DI.

+1
Oct 22 '08 at 18:09
source share

This is really a sleep problem. The Windsor built in Typed Factory Facility will give you the benefits of using a factory without these drawbacks.

0
Apr 23 2018-11-11T00:
source share



All Articles