Я пытаюсь реализовать IoC в своем приложении.У меня есть эта модель:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
В какой-то момент в моем приложении мне нужно получить IComponent
.Мое приложение использует контейнер IoC (Unity).Я могу зарегистрировать Service
в контейнере, но я не могу сделать то же самое для Component
b / c его зависимости runtimeValue
.В соответствии с this я должен использовать фабрику и вводить, что везде, где мне нужно получить 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)
}
... и зарегистрировать делегат с контейнером как статическую фабрику, чтобы он вызывал контейнер для разрешенияслужба (я использую Unity 1.2 в .net 2.0):
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 обеспокоены?