在这种情况下如何使用 Castle Windsor 类型的工厂?

How to use Castle Windsor typed factory in this case?

简单的 DI 示例:

public interface INumberToWordConverter
{
    string ConvertNumber(int number);
}

public interface IOutputManager
{
    void Write<T>(string who, T what);
}

public interface INumberProvider
{
    int GenerateNumber();
}

public class PlayWithDI
{
    private IOutputManager _outputManagerService;
    private INumberProvider _numberProviderService;
    private INumberToWordConverter _numberToWordConverterService;

    private PlayWithDI() { }
    public PlayWithDI(
        IOutputManager outputManagerService,
        INumberProvider numberProviderService,
        INumberToWordConverter numberToWordConverterService)
    {
        if (outputManagerService == null)
            throw new ArgumentNullException(nameof(outputManagerService));
        if (numberProviderService == null)
            throw new ArgumentNullException(nameof(numberProviderService));
        if (numberToWordConverterService == null)
            throw new ArgumentNullException(nameof(numberToWordConverterService));

        _outputManagerService = outputManagerService;
        _numberProviderService = numberProviderService;
        _numberToWordConverterService = numberToWordConverterService;
    }

    public void Execute()
    {
        int number = _numberProviderService.GenerateNumber();
        string wordOfNumber = _numberToWordConverterService.ConvertNumber(number);
        _outputManagerService.Write(nameof(PlayWithDI), wordOfNumber);
    }

示例实现(只是 ctors):

// Implements INumberProvider
public RandomNumberProvider(
        int min, int max,
        IOutputManager outputManagerService)
{
    ...
}

// Implements INumberToWordConverter
public ItalianNumberToWordConverter(
      IOutputManager outputManagerService)
{
    ...
}

// Implements IConsoleManager
public ConsoleOutputManager()
{
    ...
}

如果我知道 minmax 给了 RandomNumberProvider,我会这样解决:

    public void Install(
        IWindsorContainer container, 
        IConfigurationStore store)
    {
        container.Register(
            Component.For<PlayWithDI>());

        container.Register(
            Component.For<IOutputManager>()
            .ImplementedBy<ConsoleOutputManager>());

        container.Register(
            Component.For<INumberProvider>()
            .ImplementedBy<RandomNumberProvider>()
            .DependsOn(
                Dependency.OnValue("min", 2),
                Dependency.OnValue("max", 20)));

        container.Register(
            Component.For<INumberToWordConverter>()
            .ImplementedBy<ItalianNumberToWordConverter>());
    }

...
container.Install(new DependenciesConfiguration1());
var testDI = container.Resolve<PlayWithDI>();
testDI.Execute();

当我想在运行时为 RandomNumberProvider 提供自定义参数时出现问题。

我看了一下TypedFactory,但是这个例子我不是很懂,因为如果我先解析一个factory,那么PlayWithDi应该怎么解析呢?我应该将 INumberProviderFactory 而不是 INumberProvider 传递给它的构造函数吗?

在这种情况下,我想到了这样一个工厂:

public interface INumberProviderFactory
{
    INumberProvider Create(
        IOutputManager outputManager, 
        int min, int max);
}

当我再调用Create时,我应该如何解析outputManager呢?我很困惑。

The problem arises when I want to give custom parameters to RandomNumberProvider at runtime.

这就是你出错的地方。 Injecting runtime data into components during construction is ananti-pattern:

Don't inject runtime data into application components during construction; it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration. [...] Let runtime data flow through the method calls of constructed object graphs.

换句话说,您的 RandomNumberProvider 应该接受 minmax 参数是 GenerateNumber 方法的输入参数。