使用Spring.Net进行WebService开发(三)Spring.Net容器相关知识

本来准备这一篇说说NHibernate,但是考虑到如果有没有接触过Java的Spring框架的同学,可能有很多地方都不明白,所以决定把一些基本概念说明一下。

首先来说说什么是Spring容器?

当你在一个对象中需要使用另一个对象的时候,最直接的办法当然是把它new出来。好了,现在我加一个限制,这个对象里有一些内部状态,我希望这些状态共享给所有访问这个对象的人,此时又怎么做呢?给需要共享的数据和方法加static就好了。好,现在已经满足前面的需求了,现在新的需求又来了,如果需要通过继承来扩展这些共享数据和方法呢?现在已经不可能了,因为选择静态就等于失去了多态。所以,一般工具类会采用这种方式,比如Math类,一般工具类不需要进行扩展和修改,所以这样可行。

除了这一点,static所能控制的只有对应用程序级别的限制,也就是说这个对象要么大家各用各的,要么就都用同一个,不能再分到更细的范围(scope),比如我希望同一个用户使用同一个对象,不同用户使用不同对象,因此容器便出现了。

想到这一点很简单,既然大家都要用,那我就把它放到一个公共的地方去,大家都到那去取,这个地方就是容器,容器可以为对象的范围做出更多的控制。

singleton 每次获取都返回同一个实例,就是单例
prototype 每次获取都返回新的实例,就是每次都new
request 对一个HTTP请求,每次获取都返回同一个实例
session 对一个HTTP session,每次获取都返回同一个实例
application 对一个web application,每次获取都返回同一个实例

前两者一般在桌面程序中使用,后三者一般在web程序中需用,使用后三者需要Spring.Web

<object id="Foo" type="SpringNetDI.Foo" />
<object id="Foo" type="SpringNetDI.Foo" singleton="true" />

桌面程序中以上两种写法等价,就是singleton

<object id="Foo" type="SpringNetDI.Foo" singleton="false"/>
以上写法就是prototype

在web程序中,使用scope来设置相应范围,如:

<object id="Foo" type="SpringNetDI.Foo" scope="prototype"/>


好了,现在我们已经知道如何将对象放进容器中了,那么如何将对象取出呢,是我们自己来取吗?

根据IoC(Inversion of Control)概念,我们需要的对象应该是容器主动提供的,即依赖注入(DI)。

当然,实现依赖注入需要一个前提,就是对象不能离开容器管理范围,即需要被完成注入的对象必须由容器来创建,这时容器才能把它需要的对象注入进去,当然,这些被注入的对象也来自容器。

Spring.Net为我们提供了多种注入手段,最常用的是构造函数注入和属性注入,在下面这个例子中,Foo和Bar通过不同方式注入到FooBar对象中。

通过构造函数注入时,我们一般只是在构造时使用该对象,此后便不再需要该对象。如果后续需要持续使用该对象,那么一般通过属性注入,这一点不得不说C#的自动属性要比Java的get、set方法方便多了。

public interface ICall
{
    void Call();
}

public class Foo : ICall
{
    public Foo()
    {
        Console.Out.WriteLine("Foo Constracted.");
    }

    public void Call()
    {
        Console.Out.WriteLine("Foo Called.");
    }
}

public class Bar : ICall
{
    public Bar()
    {
        Console.Out.WriteLine("Bar Constracted.");
    }

    public void Call()
    {
        Console.Out.WriteLine("Bar Called.");
    }
}

public class FooBar
{
    public ICall Call { get; set; }

    public FooBar(ICall call)
    {
        call.Call();
    }

    public void CallInternal()
    {
        Call.Call();
    }
}

配置如下:

  <object id="Foo" type="SpringNetDI.Foo" />
  <object id="Bar" type="SpringNetDI.Bar" />
  <object id="FooBar" type="SpringNetDI.FooBar">
    <!--属性注入-->
    <property name="Call" ref="Foo" />
    <!--构造函数注入-->
    <constructor-arg name="call" ref="Bar"/>
  </object>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值