Структура разрешения типа с параметрами - PullRequest
1 голос
/ 01 сентября 2010

У меня проблема .... Скажем так, у меня есть такой класс:

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 (), mapmap выдает ошибку, потому что нет записи в реестре для параметра FileInfo. Параметр класса A (FileInfo) создается в классе B; Я знаю, что могу сделать: ObjectFactor.GetInstance () и передать параметры, но я хочу, чтобы внедрение зависимости не предоставляло сервис. И я хочу, чтобы, когда я делаю ObjectFactory.GetInstance (), чтобы построить весь граф объекта.

Как это сделать?

1 Ответ

4 голосов
/ 02 сентября 2010

Вы можете использовать инструкцию Ctor, чтобы сообщить SM, какие объекты использовать для параметров Ctor.

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

Подробнее об аргументах Ctor здесь .

Редактировать: В случае, если имя файла неизвестно до выполнения метода Do в B, вы должны отложить создание объекта A до выполнения метода do.Для этого вы можете использовать фабрику, либо с ручным кодированием, либо с Func / Lazy.

Для подхода с Func вы можете изменить свой B, чтобы он брал Func of A в качестве зависимости 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>();
  }
);
...