Search code examples
c#.netinversion-of-controlcastle-windsor

Can i inject component without interface use windsor


I like ioc. Earlier, i use Spring in Java, now, i want use DI in C#. I found castle.windsor. But it does not seem to direct injection class.

Now, I try this, but fail.... Someone, can you help me fix it? Or, tell me, What DI framework can i use?

Program.cs

using System;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace InjectionConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new WindsorContainer();
            container.Install(new MainInstaller());

            var service1 = container.Resolve<Service1>();

            service1.Say();

            // clean up, application exits
            container.Dispose();

            Console.ReadKey();
        }
    }

    class MainInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Classes.FromThisAssembly());
        }
    }
}

Service1.cs

using System;

namespace InjectionConsole
{
    class Service1
    {
        private Service2 Service2 { get; set; }

        public void Say()
        {
            Console.WriteLine("Hello, I m Service 1, let me call Service 2");

            Service2.Say();
        }
    }
}

Service2.cs

using System;

namespace InjectionConsole
{
    class Service2
    {
        public void Say()
        {
            Console.WriteLine("Hello, I m Service 2");
        }
    }
}

Solution

  • My answer is similar to another but with one hair-splitting difference:

    public class Service1
    {
        private readonly Service2 _service2;
    
        public Service1(Service2 service2) {
            _service2 = service2;
        }
    
        public void Say()
        {
            Console.WriteLine("Hello, I m Service 1, let me call Service 2");
    
            _service2.Say();
        }
    }
    

    First, the class itself would be written exactly the same way whether or not you're using a container like Windsor. The class has to "get" its dependency (an instance of Service2) from somewhere. So we put it in the constructor. Service1 expects whatever creates it to supply a Service2. Since you're using the container, the container creates Service1, it sees in the constructor that it needs a Service2, and it supplies that.

    Making _service2 a readonly field emphasizes that once it's created (the constructor is done executing) Service1 has no further control over the value of _service2. It's set and cannot be changed, not even within Service1. That's important because we don't want Service1 to control that dependency. We want it to require that dependency. It just takes whatever value is passed in and uses it.

    Again, that's a hair-splitting difference. If you don't make _service2 readonly you probably wouldn't change it anyway. But this makes clear that you can't change it.