如何使Simple Injector对同一接口使用不同的具体类,但使用不同的类

时间:2019-06-07 23:53:59

标签: c# inversion-of-control simple-injector

我可以使用构造函数注入使用StructureMap做到这一点。但是我找不到使用简单注入器执行此操作的方法。这是一些说明此情况的代码(对不起,长度)

我已经在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");
}

1 个答案:

答案 0 :(得分:1)

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