我可以在没有接口的情况下使用windsor注入组件

时间:2016-07-23 17:22:57

标签: c# .net inversion-of-control castle-windsor

我喜欢ioc。早些时候,我在Java中使用Spring,现在,我希望在C#中使用DI。 我找到了castle.windsor。但它似乎没有直接注射类。

现在,我试试这个,但失败了......有人,你能帮我解决一下吗?或者,告诉我,我可以使用哪种DI框架?

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

3 个答案:

答案 0 :(得分:1)

我假设您想在Service1实例中解析Service2。你可以通过构造函数注入实现它

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

答案 1 :(得分:1)

您似乎没有将Service1Service2类标记为public,这将使它们默认为内部。 Classes.FromThisAssembly()方法仅加载公共类型,除非您明确告诉它加载非公共类型(顺便说一句,这是不鼓励的!)。检查城堡windsor GitHub文档页面上的the docs

答案 2 :(得分:0)

我的回答类似于另一个,但有一个分裂的差异:

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

首先,无论您是否使用像Windsor这样的容器,类本身的编写方式都完全相同。该类必须从某处“获取”其依赖项(Service2的实例)。所以我们把它放在构造函数中。 Service1期望创建它的任何内容都提供Service2。由于您正在使用容器,容器会创建Service1,它会在构造函数中看到它需要Service2,并且它会提供该容器。

使_service2 readonly字段强调一旦创建(构造函数已完成执行),Service1无法进一步控制_service2的值。它已设置且无法更改,即使在Service1内也无法更改。这很重要,因为我们不希望Service1 控制这种依赖。我们希望它要求那种依赖。它只需要传入任何值并使用它。

同样,这是一个分裂的差异。如果您制作_service2 readonly,您可能无论如何都不会改变它。但这表明你无法改变它。