Castle Windsor: повторно использовать разрешенный компонент в OnCreate, UsingFactoryMethod или DynamicParameters - PullRequest
0 голосов
/ 30 апреля 2010

Я пытаюсь выполнить действие с разрешенным компонентом, прежде чем оно будет возвращено как зависимость от приложения.

Например, с этим графиком:

public class Foo : IFoo { }

public class Bar {
  IFoo _foo;
  IBaz _baz;
  public Bar(IFoo foo, IBaz baz) {
    _foo = foo;
    _baz = baz;
  }
}

Когда я создаю экземпляр IFoo, я хочу, чтобы контейнер создавал экземпляр Bar и передавал ему уже разрешенный IFoo вместе с любыми другими зависимостями, которые ему требуются. Поэтому, когда я звоню:

var foo = container.Resolve<IFoo>();

Контейнер должен автоматически вызвать:

container.Resolve<Bar>(); // should pass foo and instantiate IBaz

Я пытался использовать OnCreate, DynamicParameters и UsingFactoryMethod, но проблема, которую они все разделяют, заключается в том, что они не содержат явной ссылки на компонент: DynamicParameters вызывается до создания экземпляра IFoo. OnCreate вызывается после, но делегат не передает экземпляр. Использование FactoryMethod не помогает, потому что мне нужно зарегистрировать эти компоненты в TService и TComponent.

В идеале, я бы хотел, чтобы регистрация выглядела примерно так:

container.Register<IFoo, Foo>((kernel, foo) => kernel.Resolve<Bar>(new { foo }));

Обратите внимание, что IFoo и Bar зарегистрированы с временным образом жизни, что означает, что уже разрешенный экземпляр должен быть передан в Bar - он не может быть "повторно разрешен".

Возможно ли это? Я что-то упустил?

1 Ответ

1 голос
/ 01 мая 2010

Кажется, это то, что вы хотите:

public interface IFoo {}
public class Foo : IFoo {}
public class Bar {
    public IFoo BarFoo { get; private set;}

    public Bar(IFoo foo) {
        BarFoo = foo;
    }

    public void DoSomething() {
        Console.WriteLine("Initializing");
    }
}

[Test]
public void Create() {
    var container = new WindsorContainer();
    var initialized = false;
    container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Transient
        .OnCreate((kernel, foo) => {
            var bar = kernel.Resolve<Bar>(new {foo});
            Assert.AreSame(foo, bar.BarFoo);
            bar.DoSomething();
            initialized = true;
        }));
    container.Register(Component.For<Bar>().LifeStyle.Transient);
    var f = container.Resolve<IFoo>();
    Assert.IsTrue(initialized);
}

На самом деле это почти дубликат этого другого вопроса .

...