开发者

Structuremap resolve type with parameters

开发者 https://www.devze.com 2023-01-13 20:18 出处:网络
I have a problem.... Lest say I have a class like this one: public class A: InterfaceA { private FileInfo _fileInfo = null;

I have a problem.... Lest say I have a class like this one:

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

    ...
}

and another one:

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

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

Now, I have setup StructureMap registers like this:

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

and when I execute B.Do() structuremap will throw an error because there is no registry entry for FileInfo parameter. The parameter of class A (FileInfo) is constructed in class B; I know that I can do: ObjectFactor.GetInstance() and pass parameters, but I want Dependency injection not service provider. And I want that when I do ObjectFactory.GetInstance(), to construct en开发者_Go百科tire object graph.

How to do this?


You can use the Ctor instruction to tell SM what objects to use for the Ctor parameters.

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

Read more about Ctor arguments here.

Edit: In case the file name is not known until the execution of the Do method in B, you have to postpone the creation of the A-object until the do method is executed. In order to do so you can use a factory, either hand coded or a Func/Lazy.

For a Func approach you can change your B to take a Func of A as ctor dependency:

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

Boot strap it using:

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

精彩评论

暂无评论...
验证码 换一张
取 消