Injection into Console Application with the Simple Injector

19,018

Solution 1

You need to make Bootstrap.container available in Program.Main and then use it to create instances of classes instead of directly calling their constructors directly:

_testInjectedClass = Bootstrap.container.GetInstance<ITestInjectedClass>();

Of course you will need to expose it in Bootstrap for that to work:

class Bootstrap
{
    public static Container container;

    public static void Start()
    {
        container = new Container();

        // Register your types, for instance:
        container.Register<IUserRepository, UserRepository>(Lifestyle.Singleton);
        container.Register<ITestInjectedClass, TestInjectedClass>(Lifestyle.Singleton);
        //container.Register<IUserRepository, TestInjectedClass>(Lifestyle.Singleton);
        //container.Register<IUserContext, WinFormsUserContext>();
        container.Register<TestInjectedClass>();

        // Optionally verify the container.
        container.Verify();
    }
}

And call Bootstrap.Start from Program.Main:

static void Main(string[] args)
{ 
    Bootstrap.Start();

    _testInjectedClass = Bootstrap.container.GetInstance<ITestInjectedClass>();
    _testInjectedClass.UserRepoRun();

    Console.ReadLine();
}

Solution 2

The problem is because you are calling your Bootstrap code in Program class instance constructor.

So, actually when you start your program the execution environment, is calling entry point method Main. And your instance constructor is never executed.

Try changing your entry point method Main and 'Bootstrap' class code:

static void Main(string[] args)
{ 
     var container = new Container();
     Bootstrap.Start(container);
     _testInjectedClass = container.GetInstance<TestInjectedClass>();
     _testInjectedClass.UserRepoRun();

     Console.ReadLine();
}

class Bootstrap
{
    public static void Start(Container container)
    {
        // Register your types, for instance:
        container.Register<IUserRepository, UserRepository>(Lifestyle.Singleton);
        container.Register<ITestInjectedClass, TestInjectedClass>(Lifestyle.Singleton);
        container.Register<TestInjectedClass>();

        // Optionally verify the container.
        container.Verify();
    }
}
Share:
19,018
stackada
Author by

stackada

Updated on June 12, 2022

Comments

  • stackada
    stackada almost 2 years

    I am using Simple Injector for test purpose but pretty new on OOP. I am trying to create loosely couple classes. Here is the my scenario.

    I have User repo and interface like this.

    public class UserRepository : IUserRepository
    {
        public void Add(Model.User user)
        {
            Console.WriteLine("Name:"+user.Name+"\n"+"SurName:"+user.SurName);
        }
    
        public void Delete(int id)
        {
            throw new NotImplementedException();
        }
    }
    
    public interface IUserRepository
    {
        void Add(User user);
        void Delete(int id);
    }
    

    My TestInjectedClass Class and interface are something like this which I am planning to use in Program Main.

    public class TestInjectedClass : ITestInjectedClass
    {
        private readonly IUserRepository _userRepository;
        public TestInjectedClass(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }
    
        public void UserRepoRun()
        {
            var user = new User() {Id = 1,Name = "ada",SurName = "stack"};
            _userRepository.Add(user);
        }
    }
    public interface ITestInjectedClass
    {
        void UserRepoRun();
    }
    

    And My console program looks like this:

    class Program 
    {
        static ITestInjectedClass _testInjectedClass;
        private static IUserRepository _userRepository;
        static void Main(string[] args)
        { 
            _testInjectedClass= new TestInjectedClass(_userRepository);
            _testInjectedClass.UserRepoRun();
    
            Console.ReadLine();
        }
        public Program()
        {                 
            Bootstrap.Start();
        }
    

    }

    BootStrap class here:

    class Bootstrap
    {
        public static void Start()
        {
            var container = new Container();
    
            // Register your types, for instance:
            container.Register<IUserRepository, UserRepository>(Lifestyle.Singleton);
            container.Register<ITestInjectedClass, TestInjectedClass>(Lifestyle.Singleton);
            //container.Register<IUserRepository, TestInjectedClass>(Lifestyle.Singleton);
            //container.Register<IUserContext, WinFormsUserContext>();
            container.Register<TestInjectedClass>();
    
            // Optionally verify the container.
            container.Verify();
        }
    }
    

    My problem when I run program, I am getting a value exception on the _userRepository inside TestInjectionClass. How can I properly inject TestInjectionClass and UserRepository to Main Program. Thanks

  • Steven
    Steven almost 9 years
    I made a small tweak to your answer. It's better to resolve the main class directly from the container, instead of creating it manually and resolve its dependencies.