Как справиться с этим сценарием разрешения DI? - PullRequest
0 голосов
/ 10 марта 2012

Итак, давайте предположим, что я могу рисовать в краске:

Horrible depiction of my problem

Скажем, у меня есть класс A, который зависит от объектов B и C, которые будут созданы, но C также зависит от экземпляра B, и я хочу, чтобы этот экземпляр B был таким же, как я передаю A.Как я могу это сделать?

Теперь вы, вероятно, тоже этого не понимали;так что я пойду дальше и превращу это в код:

public class A
{
    private readonly B b;
    private readonly C c;

    public A(B b, C c)
    {
        this.b = b;
        this.c = c;
    }
}

public class B
{    
}

public class C
{
    private readonly B b;

    public C(B b)
    {
        this.b = b;
    }
}

Без DI я бы разрешил это так:

var b = new B();
var c = new C(b);
var a = new A(b,c);

Как я могу сделать что-то подобное через DI,чисто?То, что я хочу, довольно просто: используйте один и тот же экземпляр B при создании экземпляров как C, так и A.

. Забыл упомянуть, что я действительно хочу использовать этот метод для каждого веб-запроса, а не для одногоили переходный процесс.

Ответы [ 3 ]

1 голос
/ 10 марта 2012

Согласно документации к замку , поведение синглтона уже используется по умолчанию.Следовательно, Castle создаст только один экземпляр B и передаст его A и C.

Это случаи, когда вы не хотите этого, о чем вам следует беспокоиться.Затем вам потребуется дополнительная настройка, как описано в соответствующей документации.

0 голосов
/ 10 марта 2012

Предполагая, что вы действительно хотите, чтобы B не подвергался воздействию в классе C, как насчет этого:

class Program
{
  static void Main(string[] args)
  {
     var b = new B();
     var c = new C(b);
     var a = c.GetA();
  }
}

public class A
{
  private readonly B b;
  private readonly C c;

  public abstract class AFactory
  {
     private B b;

     public AFactory(B b)
     {
        this.b = b;
     }

     protected A GetA(C c)
     {
        return new A(b, c);
     }

     abstract public A GetA();
  }

  private A(B b, C c)
  {
     this.b = b;
     this.c = c;
  }
}

public class B
{
}

public class C
{
  private readonly B b;
  private CAFactory afactory;

  private class CAFactory : A.AFactory
  {
     private C c;
     public CAFactory(C c) : base(c.b)
     {
        this.c = c;
     }

     public A GetA()
     {
        return GetA(c);
     }
  }

  public C(B b)
  {
     this.b = b;
     afactory = new CAFactory(this);
  }

  public A GetA()
  {
     return afactory.GetA();
  }
}
0 голосов
/ 10 марта 2012

вижу два варианта. Во-первых, используйте свой контейнер для управления временем жизни class:

StructureMap Container, охват IUnitOfWork до текущего HttpContext:

For<IUnitOfWork>().HttpContextScoped().Use<UnitOfWork>();

Это гарантирует, что все запросы для IUnitOfWork в одном и том же HttpContext имеют один и тот же экземпляр.

Вариант второй, рефакторинг вашего кода, чтобы у вас не было этой проблемы ...

...