Structuremap解析带参数的类型

时间:2010-09-01 13:43:32

标签: parameters dependency-injection constructor structuremap

我有问题.... 不要说我有这样一个班级:

public class A: InterfaceA
{
    private FileInfo _fileInfo = null;
    public A(FileInfo fileInfo)
    {
        this._fileInfo = fileInfo;
    }

    ...
}

另一个:

public class B: InterfaceB
{
    private A _classA = null;
    public B(A classA)
    {
        this._classA = classA;
    }

    public void Do()
    {
        FileInfo fi = new FileInfo(...);
        _classA.DoSomething();
    }
}

现在,我已经设置了这样的StructureMap寄存器:

For<InterfaceA>().Use<A>();
For<InterfaceB>().Use<B>();

当我执行B.Do()时,structmap将抛出一个错误,因为FileInfo参数没有注册表项。 A类(FileInfo)的参数在B类中构造; 我知道我可以做:ObjectFactor.GetInstance()并传递参数,但我希望依赖注入不是服务提供者。当我做ObjectFactory.GetInstance()时,我想要构建整个对象图。

怎么做?

1 个答案:

答案 0 :(得分:4)

您可以使用Ctor指令告诉SM用于Ctor参数的对象。

var myFile = new FileInfo(...);
For<InterfaceA>.Use<A>().Ctor<FileInfo>().Is(myFile);

详细了解Ctor参数here

修改 如果在B中执行Do方法之前不知道文件名,则必须推迟创建A对象,直到执行do方法。为此,您可以使用手工编码的工厂或Func / Lazy。

对于Func方法,您可以更改B以将A的Func作为ctor依赖项:

public class B : InterfaceB
{
  private readonly Func<string, InterfaceA> _aBuilder;
  public B(Func<string, InterfaceA> aBuilder)
  {
    _aBuilder = aBuilder;
  }

  public void Do()
  {
    InterfaceA anA = _aBuilder("fileName");
    anA.DoSomething();
  }
}

使用以下方式启动它:

ObjectFactory.Initialize(
  c=>
  {
    c.For<InterfaceA>().Use<A>();
    c.For<Func<string, InterfaceA>>().Use(d => 
      new Func<string, InterfaceA>( s => 
        ObjectFactory.With(new FileInfo(s)).GetInstance<InterfaceA>()));
    c.For<InterfaceB>().Use<B>();
  }
);