Я пытаюсь разработать библиотеку, использующую подход для инъекций зависимости (с Ninject), и у меня возникает какая-то путаница из-за моего неправильного дизайна. Итак, мой подход к дизайну
- Объект
parent
имеет объектcommon
. - Объект
parent
использует некоторое переменное число объектовchild
. - Все объекты
child
должны использовать тот же экземпляр объектаcommon
с объектомparent
Вот простая модель моей проблемной области.
interface IParent : IDisposable {
void Operation();
}
interface ICommon : IDisposable {
void DoCommonThing();
}
interface IChild1 {
void DoSomething();
}
interface IChild2 {
void DoAnotherThing();
}
class Parent : IParent {
private readonly ICommon _common;
public Parent(ICommon common) {
_common = common;
}
public void Dispose() {
_common.Dispose();
}
public void Operation() {
var c1 = ObjectFactory.GetInstance<IChild1>();
c1.DoSomething();
var c2 = ObjectFactory.GetInstance<IChild2>();
c2.DoAnotherThing();
// number of childs vary, do things until cn
_common.DoCommonThing();
}
}
class Common : ICommon {
private bool _isDisposed;
public void Dispose() {
_isDisposed = true;
}
public void DoCommonThing() {
if (_isDisposed)
throw new Exception("Common Object is Disposed");
}
}
class Child1 : IChild1
{
private readonly ICommon _common;
public Child1(ICommon common) {
_common = common;
}
public void DoSomething() {
// Do Something...
_common.DoCommonThing();
}
}
class Child2 : IChild2 {
private readonly ICommon _common;
public Child2(ICommon common) {
_common = common;
}
public void DoAnotherThing() {
// Do Another Thing...
_common.DoCommonThing();
}
}
Проблема 1
Количество необходимых объектов child
меняется. Например, согласно возвращаемому значению c1.DoSomething
, я могу или не нуждаюсь в других дочерних объектах. Поэтому я не хочу вводить их через конструктор и просто создавать их, когда они нужны. Но этот подход вызывает нарушение Голливудского принципа.
Вопрос 1
Как это нарушение может быть предотвращено, без ввода дочерних объектов через конструктор?
Проблема 2
Я хочу, чтобы объекты child
использовали тот же экземпляр объекта common
с их объектом parent
. Таким образом, время жизни объекта common
должно быть таким же, как и его родитель.
-
Если для ICommon не определено время жизни, тогда все объекты
child
будут иметь свой собственный экземпляр объектаcommon
. -
Если время жизни ICommon определено в области Thread или Request, я не могу использовать разные экземпляры объекта
parent
в той же области Thread или Request. Поскольку каждый объектparent
должен использовать свой собственный новыйcommon
объект и удалять его.
Так что я не мог решить эту проблему, используя параметры времени жизни, которые я знаю. Я создал другое решение для этой второй проблемы, но это ухудшает код.
Во-первых, вместо того, чтобы вставлять ICommon
в объект parent
, объект parent
, он сам создает его через ObjectFactory
class Parent : IParent {
private readonly ICommon _common;
public Parent() {
_common = ObjectFactory.GetInstance<ICommon>();
}
.....
Затем вместо того, чтобы вставлять ICommon
в объект child
, объект parent
устанавливает объект common
дочерних объектов.
interface IChild {
ICommon Common { get; set; }
}
interface IChildN : IChild {
void DoNthThing();
}
abstract class ChildBase : IChild {
ICommon IChild.Common { get; set; }
}
class ChildN : IChildN {
public void DoNthThing() { }
}
class Parent : IParent {
private readonly ICommon _common;
public void Operation() {
var c1 = ObjectFactory.GetInstance<IChild1>();
c1.Common = _common;
c1.DoSomething();
var c2 = ObjectFactory.GetInstance<IChild2>();
c2.Common = _common;
c2.DoAnotherThing();
_common.DoCommonThing();
}
}
Но это решение снова нарушает принцип Голливуда, и я должен установить свойство Common каждого объекта child
.
Вопрос 2
Как объект parent
распределяет объект common
с объектами child
, используя Injection Dependency? (предпочтительно с Ninject)
Вопрос 3
Это немного более общая информация о моей проблеме: как может инъекция зависимостей правильно применяться к этой модели?
ПРИМЕЧАНИЕ: ObjectFactory.GetInstance
вызывает Kernel.Get
для Ninject