我怎样才能使简单注入器对同一接口使用不同的具体 类,但具有不同的 类

How can I cause Simple Injector to use different concrete classes for the same interface, but with different classes

我可以使用构造函数注入对 StructureMap 执行此操作。但是我找不到使用 Simple Injector 执行此操作的方法。这是一些说明这一点的代码(抱歉长度)

我查看了 Register 方法中的 lambda,但似乎无法理解如何调用容器的单个应用程序范围实例来获取我需要的一个实例。

这些是我想要构建的对象图:

var bannerTalker =
    new LoudMouth(
        new ConsoleShouter(), // Implements IConsoleVoicer
        new ObnoxiousBannerGenerator());

var plainTalker = 
    new TimidSpeaker(
        new ConsoleWhisperer());  // Implements IConsoleVoicer

Here's the code:

``` c#
public interface IConsoleVoicer
{
    void SaySomething(string whatToSay);
}

public class ConsoleWhisperer : IConsoleVoicer
{
    public void SaySomething(string whatToSay)
    {
        Console.WriteLine(whatToSay?.ToLower());
    }
}

public class ConsoleShouter : IConsoleVoicer
{
    public void SaySomething(string whatToSay)
    {
        Console.WriteLine(whatToSay?.ToUpper());
    }
}

public interface IBannerGenerator
{
    string GetBanner();
}

public class ObnoxiousBannerGenerator : IBannerGenerator
{
    public string GetBanner()
    {
        return "OBNOXIOUS";
    }
}

public interface IBannerTalker
{
    void SayWithBanner(string somethingToSay);
}

public class LoudMouth : IBannerTalker
{
    private IConsoleVoicer Voicer { get; set; }
    private IBannerGenerator BannerGenerator { get; set; }

    public LoudMouth(
        IConsoleVoicer concoleVoicer, IBannerGenerator bannerGenerator)
    {
        Voicer = concoleVoicer;
        BannerGenerator = bannerGenerator;
    }

    public void SayWithBanner(string somethingToSay)
    {
        Voicer.SaySomething(string.Format("{0}:{1}",
            BannerGenerator.GetBanner(), somethingToSay));
    }
}

public interface IPlainTalker
{
    void SayIt(string somethingToSay);
}

public class TimidSpeaker : IPlainTalker
{
    private IConsoleVoicer Voicer { get; set; }

    public TimidSpeaker(IConsoleVoicer concoleVoicer)
    {
        Voicer = concoleVoicer;
    }

    public void SayIt(string somethingToSay)
    {
        Voicer.SaySomething(somethingToSay);
    }
}

这就是我尝试过的:

static void Main(string[] args)
{
    var container = new Container();
    container.Register<IBannerGenerator, ObnoxiousBannerGenerator>();

    container.Register<IPlainTalker, TimidSpeaker>();
    container.Register<IBannerTalker, LoudMouth>();

    //HERE IS THE DILEMMA! How do I assign
    // to IBannerTalker a A LoudMouth contructed with a ConsoleShouter,
    // and to IPlainTalkerTalker a A TimidSpeaker contructed with a ConsoleWhisperer 

    //container.Register<IConsoleVoicer, ConsoleShouter>();
    container.Register<IConsoleVoicer, ConsoleWhisperer>();

    var bannerTalker = container.GetInstance<IBannerTalker>();
    var plainTalker = container.GetInstance<IPlainTalker>();

    bannerTalker.SayWithBanner("i am a jerk");
    plainTalker.SayIt("people like me");
}

Ric .Net 正确地指出了 RegisterConditional 方法。以下注册完成您的任务:

container.Register<IBannerGenerator, ObnoxiousBannerGenerator>();

container.Register<IPlainTalker, TimidSpeaker>();
container.Register<IBannerTalker, LoudMouth>();

container.RegisterConditional<IConsoleVoicer, ConsoleShouter>(
    c => c.Consumer.ImplementationType == typeof(LoudMouth));
container.RegisterConditional<IConsoleVoicer, ConsoleWhisperer>(
    c => c.Consumer.ImplementationType == typeof(TimidSpeaker));