Spring.Services命名空间的目的是为业务服务提供位置的透明性。我们相信使用普通的接口和.NET类,用户应该可以用最简单的方式实现服务。我们也认为在将某个服务发布给客户端的时,应该只关心服务的配置,而无需关心服务的实现。
在Spring.Services命名空间的支持下,可以用IoC容器中的服务导出对象将任一个普通对象发布为web服务、企业服务组件或远程对象。这里说的“普通对象”是指不继承或应用基础框架中任何特殊的基类(如MarshalByRefObject)或特性(如WebMethod)的对象。目前Spring.NET要求要发布的对象必须实现一个业务接口(按:即要发布的类必须实现某个接口,但这并非是限制,毕竟面向接口无论在什么时候都是好的编程实践)。Spring.NET的Remoting导出类会自动为其创建一个继承自MarshalByRefObject代理类。在服务端,可以将SAO类型注册为SingleCall或Singleton模式,也可以为每个对象配置生存期和租赁时间。另外,还可以将应用了AOP通知的对象发布为SAO。在客户端,可以用面向接口的最佳编程方式获取CAO的代理对象。Spring.NET还为Remoting创建了专门的schema来简化xml配置,不过我们仍然可以使用标准的schema来创建对象定义。
传统方式,在服务器需要使用RemotingConfiguration.Configure("xxx.exe.config")的方式启动服务,在客户端需要IContract contract = (IContract) Activator.GetObject ( typeof (IContract ), "tcp://localhost:1800/xxxx")的方式来注册服务。现在,一切都由Spring.NET而随之改变。
准备条件:
[Serializable]
public class Person { public string Name { get; set; } public int Age { get; set; } } public interface IPersonContract { void SavePerson(Person model); Person GetPerson(); }
PersonContract
public class PersonContract : IPersonContract { private Person m_person; public void SavePerson(Person model) { this.m_person = model; this.m_person.Name += "冬"; this.m_person.Age++; } public Person GetPerson() { return this.m_person; } }
一、部署为Singleton模式:
服务端
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core" /> </sectionGroup> </configSections>
<spring> <parsers> <parser type="Spring.Remoting.Config.RemotingNamespaceParser, Spring.Services" /> </parsers> <context> <resource uri="config://spring/objects" /> </context> <objects xmlns="http://www." xmlns:r="http://www./remoting"> <object id="personContract" type="RemotingServer.PersonContract, RemotingServer"/> <!--自动配置服务--> <r:configurer filename="RemotingServer.exe.config" /> <!--目标对象名和服务名--> <r:saoExporter targetName="personContract" serviceName="PersonRemotingServer" /> </objects> </spring> <system.runtime.remoting> <application> <channels> <channel ref="tcp" port="1800" /> </channels> </application> </system.runtime.remoting> </configuration>
Program
class Program { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); Console.WriteLine("服务器已启动"); Console.ReadLine(); } }
客户端
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> </sectionGroup> </configSections>
<spring> <context> <resource uri="config://spring/objects" /> </context> <objects xmlns="http://www."> <object id="PersonRemotingServer" type="Spring.Remoting.SaoFactoryObject, Spring.Services"> <property name="ServiceInterface" value="IContract.IPersonContract, IContract" /> <property name="ServiceUrl" value="tcp://localhost:1800/PersonRemotingServer" /> </object> </objects> </spring> </configuration>
Program
class Program { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); IPersonContract server = (IPersonContract)ctx.GetObject("PersonRemotingServer"); Person tempPerson = server.GetPerson(); tempPerson = tempPerson ?? new Person() { Name = "刘冬", Age = 26 }; server.SavePerson(tempPerson); Person person = server.GetPerson(); string msg = string.Format("姓名:{0},年龄:{1}", person.Name, person.Age); Console.WriteLine(msg); Console.ReadLine(); } }
运行效果:
第一次调用
第二次调用
二、部署为SingleCall模式:
修改对象的属性
<object id="personContract" type="RemotingServer.PersonContract, RemotingServer" singleton="false"/>
Program
class Program { static void Main(string[] args) { IApplicationContext ctx = ContextRegistry.GetContext(); IPersonContract server = (IPersonContract)ctx.GetObject("PersonRemotingServer"); Person tempPerson = server.GetPerson(); tempPerson = tempPerson ?? new Person() { Name = "刘冬", Age = 26 }; server.SavePerson(tempPerson); Person person = server.GetPerson(); string msg = person == null ? "对象为空" : string.Format("姓名:{0},年龄:{1}", person.Name, person.Age); Console.WriteLine(msg); Console.ReadLine(); } }
调用
|