具有静态和动态依赖关系的IoC
我试图在我的应用程序中实现IoC。 我有这个模型:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
在我的应用程序的某个时刻,我需要获得一个IComponent
。 我的应用程序使用IoC容器(Unity)。 我可以在容器中注册Service
,但是我不能对它的dependency runtimeValue
Component
b / c做同样的事情。 根据这一点,我必须使用工厂,并在需要获取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
我必须能够在容器中注册工厂,所以它必须只有静态依赖。 同时它必须能够提供创建组件所需的IService
类型的服务实例。
这是工厂实施。 我唯一能想到的就是使用Func<>
委托作为依赖关系:
class ComponentFactory : IComponentFactory
ComponentFactory(Func<IService> serviceFactoryDelegate)
IComponent CreateComponent(object runtimeValue) {
return new Component(serviceFactoryDelegate.Invoke(), runtimeValue)
}
...并将容器的委托注册为静态工厂,以便它回调容器以解析服务(我在.net 2.0上使用Unity 1.2):
Container
.Configure<IStaticFactoryConfiguration>()
.RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
现在我可以使用容器来解析ComponentProvider
并根据运行时值获取组件:
// this happens inside CompositionRoot
provider = Container.Resovle<IComponentProvider>()
component = provider.CreateAndCacheComponent("the component")
现在我对此有一些疑问:
我不高兴工厂调用new Component(...)
。 这个可怜的人是不是DI?
在工厂的构造函数中使用Func<IService>
时,好莱坞原理是否仍然存在? 我的意思是,它最终调用container.Resolve <> ...有点像SL。 唯一的区别是代码是在应用程序的容器注册部分,而不是在工厂类中。
就DI和IoC而言,这个实现有什么(其他)错误吗?
IService
直接注入工厂而不是Func
来避免它。 IService
实例 这比它需要更复杂一点。 为什么双重定向IComponentProvider
- > IComponentFactory
? 它看起来像IComponentFactory
不会增加任何好处。
像这样实现ComponentProvider
:
class ComponentProvider : IComponentProvider
{
ComponentProvider(IService service) { _service = service; }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = new Component(_service, runtimeValue);
return _component;
}
这会给你以下好处:
IComponentFactory
以及相应的实现。 IService
注册工厂 一般来说,你如何实现这取决于你真正需要什么:
“runtimeValue”在整个运行时可以相同,例如从设置中读取的连接字符串。 在这种情况下,不需要工厂/提供者,您可以简单地新建实例并将其注册到容器中。 每个需要IComponent
人在构造函数中请求一个而不是提供者。
如果“runtimeValue”在对CreateAndCacheComponent
调用之间真正发生更改,您只会实现一个工厂并将它作为依赖项CreateAndCacheComponent
。
对于问题1:在工厂中调用new
没有任何问题。 你在你的应用程序中有一个独立的实例化; 你只是让这个工厂代替了容器。
如果您需要模拟或更改实现,则只需模拟或更改工厂实现,而不是单独使用组件。
链接地址: http://www.djcxy.com/p/65663.html上一篇: IoC with static and dynamic dependencies
下一篇: Not understanding where to create IoC Containers in system architecture