Parameters 带参数的Structuremap解析类型

Parameters 带参数的Structuremap解析类型,parameters,dependency-injection,constructor,structuremap,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 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 structuremap时,会抛出一个错误,因为FileInfo参数没有注册表项。 A类FileInfo的参数在B类中构造; 我知道我可以这样做:ObjectFactor.GetInstance并传递参数,但我希望依赖注入而不是服务提供者。我希望在执行ObjectFactory.GetInstance时,能够构建整个对象图


如何执行此操作?

您可以使用Ctor指令告诉SM要将哪些对象用于Ctor参数

var myFile = new FileInfo(...);
For<InterfaceA>.Use<A>().Ctor<FileInfo>().Is(myFile);
阅读更多有关Ctor参数的信息

编辑:
如果在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>();
  }
);

您可以使用Ctor指令告诉SM Ctor参数要使用哪些对象

var myFile = new FileInfo(...);
For<InterfaceA>.Use<A>().Ctor<FileInfo>().Is(myFile);
阅读更多有关Ctor参数的信息

编辑:
如果在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>();
  }
);

是的,但是放在哪里:For.Use.Ctor.IsmyFile;我不能把它放进我的寄存器中,因为文件信息在实例化中不知道。如果文件名在DO方法的执行之前不知道,你必须去工厂的方法或者考虑把文件传递给方法。编辑我的答案包括工厂的方法。谢谢,我要去工厂。但是放在哪里:For.Use.Ctor.IsmyFile;我不能把它放入我的寄存器中,因为文件信息在实例化中不知道。如果文件名在DO方法的执行之前不知道,你必须去工厂方法或者考虑将文件传递给方法。编辑我的答案包括工厂方法。谢谢,我要去工厂:-D。