如何处理这个DI解决方案?

时间:2012-03-10 01:08:29

标签: c# dependency-injection inversion-of-control castle-windsor constructor-injection

所以,我们假设我可以画画:

Horrible depiction of my problem

假设我有一个类A,它依赖于要实例化的对象BC,但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干净地完成这样的事情? 我想要的非常简单:在BC实例化时使用相同的A实例。

忘记提及我确实想要按照网络请求的生活方式,而不是单身或短暂的。

3 个答案:

答案 0 :(得分:1)

根据castle documentation,单身行为已经是默认行为。因此,castle将只创建一个B实例并将其传递给A和C.

这是想要你应该担心的情况。您需要一些额外的配置,如链接文档中所述。

答案 1 :(得分:0)

我看到两个选项。一,使用您的容器来管理class的生命周期:

StructureMap Container,将IUnitOfWork范围限定为当前HttpContext

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

这可确保IUnitOfWorkHttpContext的所有请求具有相同的实例。

选项二,重构您的代码,这样您就不会遇到此问题......

答案 2 :(得分:0)

假设你真的想在C级保持B未曝光,那么:

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();
  }
}