I am trying to implement IoC in my application. I have this model:
interface IService; interface IComponent; class Service : IService Service() class Component : IComponent Component(IService service, object runtimeValue) { }
At some point in my application, I need to get an IComponent
. My application uses the IoC (Unity) container. I can register Service
with a container, but I cannot do the same for Component
b / c of its runtimeValue
dependency. Accordingly , I should use the factory and indicate that wherever I need to get IComponent
:
interface IComponentFactory IComponent CreateComponent(object runtimeValue) class ComponentProvider : IComponentProvider ComponentProvider(IComponentFactory factory) { } IComponent CreateAndCacheComponent(object runtimeValue) { _component = factory.CreateComponent(runtimeValue) return _component } // other methods
I should be able to register a factory with a container, so it should only have static dependencies. At the same time, it should be able to provide an instance of a service of the IService
type needed to create the component.
Here is a factory implementation. The only thing I could think of was to use the Func<>
delegate as a dependency:
class ComponentFactory : IComponentFactory ComponentFactory(Func<IService> serviceFactoryDelegate) IComponent CreateComponent(object runtimeValue) { return new Component(serviceFactoryDelegate.Invoke(), runtimeValue) }
... and register the delegate with the container as a static factory so that it returns the container to allow the service (I use Unity 1.2 on .net 2.0):
Container .Configure<IStaticFactoryConfiguration>() .RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
Now I can use the container to resolve the ComponentProvider
and get the component based on the runtime value:
// this happens inside CompositionRoot provider = Container.Resovle<IComponentProvider>() component = provider.CreateAndCacheComponent("the component")
Now I have some questions about this:
I am not happy that the factory calls new Component(...)
. Isn't that a poor man?
Is the Hollywood principle preserved when using the Func<IService>
in the factory constructor? I mean, it ends up calling the container. Recovers <> ... kind of like SL. The only difference is that the code is in the registration part of the application container, and not inside the factory class.
Is there anything (different) in this implementation as far as DI and IoC are concerned?