Search code examples
c#simple-injector

Passing class with variable through Simple Injector


Trying to teach myself SimpleInjector and I grasp the basics but need some assistance.

Essentially I want to pass an object through simple injector which I have already populated rather than a new object.

The example Case I have is as follow:

ITeaService:

    public interface ICup
{
    string CupName { get; set; }
    List<string> Ingredients { get; set; }
}
public class Cup : ICup
{
    public string CupName { get; set; }
    public List<string> Ingredients { get; set; }

}
public interface ITeaService
{
    ICup GetTea();
}

TeaService:

    public class TeaService : ITeaService
{
    private ICup _cup;

    public TeaService(ICup cup)
    {
        _cup = cup;
    }

    public ICup GetTea()
    {

        this._cup.Ingredients.Add("Tea bag");
        this._cup.Ingredients.Add("Hot water");

        return this._cup;
    }
}

Test:

 var container = new SimpleInjector.Container();
        container.Register<ITeaService, TeaService>();
        container.Register<ICup, Cup>();

        container.Verify();
        // Act
        var cp = container.GetInstance<ICup>();
        cp.CupName = "Daniel";


        var teaService = container.GetInstance<ITeaService>();
        var cup = teaService.GetTea();

Any thoughts how I pass a pre-defined Cup through? Is the variable cp where i've specified a CupName?


Solution

  • The following line is incorrect:

    container.Register<ICup, Cup>();
    

    Here you're telling SimpleInjector to create a new Cup whenever an ICup is requested. Change it to the following to always return the same Cup:

    var standardCup = new Cup();
    standardCup .CupName = "Daniel";
    container.RegisterSingleton<ICup>(standardCup );
    

    Now this test will succeed:

    var teaService = container.GetInstance<ITeaService>();
    var cup = teaService.GetTea();
    Assert.AreEqual(cup.CupName, "Daniel");
    Assert.AreEqual(cup, standardCup);
    

    EDIT: Based on comments: If you always want a new instance, but with the same name, you can do the following:

    container.Register<ICup>(() => new Cup { CupName = "Daniel"});
    

    This will run the callback to construct a Cup each time you request an ICup