Reputation: 255
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");
}
}
}
Upvotes: 0
Views: 866
Reputation: 41
It seems that you didn't mark the Service1
and Service2
classes as public
, which will make them internal by default. The Classes.FromThisAssembly()
method loads public types only, unless you explicitly tell it to load nonpublic types as well (which is discouraged by the way!). Check the docs on the castle windsor GitHub docs page.
Upvotes: 1
Reputation: 29222
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.
Upvotes: 0
Reputation: 6939
I assume you wanna resolve Service2 in your Service1 instance. You can achieve that by constructor injection
using System;
namespace InjectionConsole
{
class Service1
{
public Service1(Service2 s2) {
this.Service2 = s2;
}
private Service2 Service2 { get; set; }
public void Say()
{
Console.WriteLine("Hello, I m Service 1, let me call Service 2");
Service2.Say();
}
}
}
Upvotes: 1