上節談了談Netop.Core的對於應用系統的配置信息的處理,對於Netop.Core最核心的服務--類工廠/對象查找服務當然要用到配置服務,等下會說到。 對於NET類工廠/對象查找服務,名氣大的有Spring.Net(對應於Java的Spring--號稱輕量級中間件),為什麼還要再造一個輪子呢?如 ...
上節談了談Netop.Core的對於應用系統的配置信息的處理,對於Netop.Core最核心的服務--類工廠/對象查找服務當然要用到配置服務,等下會說到。
對於NET類工廠/對象查找服務,名氣大的有Spring.Net(對應於Java的Spring--號稱輕量級中間件),為什麼還要再造一個輪子呢?如果說Spring是輕量級的,那Netop.Core就只能是微量級的,夠用就好,學習曲線會大幅下降,學習研究代碼的時間也會大幅下降。
夠用就好,何樂而不為?況且Netop.Core的類工廠/對象查找服務除了可對本地服務進行實例化外,還對遠程服務(NET Remoting)和WCF服務進行統一的處理,就是說引用端程式通過Netop.Core的類工廠/對象查找服務實例化時,根本不知道也不用知道服務是本地的還是遠程服務(NET Remoting)或WCF服務。
Netop.Core的類工廠/對象查找服務是要對各應用服務進行配置的,就先從其配置說起:在配置文件(可查看測試程式的配置文件)Netop.Application節點下最少要配置:
<Application.ObjectLocator>
<DefaultAppObjectLocatorService>Netop.Core.LocatorService.DefaultAppObjectLocatorService,Netop.Core</DefaultAppObjectLocatorService>
<ObjectServiceAgentName>AppObjectService</ObjectServiceAgentName>
<AspectAgentName>AppAspect</AspectAgentName>
</Application.ObjectLocator>
<Application.Agent>
<Agent name="AppObjectService" type="Netop.Core.Configuration.FileAgentConfiguration,Netop.Core">
<File>Service.xml</File>
</Agent>
<Agent name="AppAspect" type="Netop.Core.Configuration.FileAgentConfiguration,Netop.Core">
<File>Aspect.xml</File>
</Agent>
</Application.Agent>
</Application.ObjectLocator>
<AspectAgentName>AppAspect</AspectAgentName>是配置AOP服務的,下一節會說到,現暫不表述。
<ObjectServiceAgentName>AppObjectService</ObjectServiceAgentName>中的AppObjectService名對應於Application.Agent下節點Agent
name="AppObjectService"的信息:
<Agent name="AppObjectService" type="Netop.Core.Configuration.FileAgentConfiguration,Netop.Core">
<File>Service.xml</File>
</Agent>
查看AppObjectLocatorConfiguration.cs文件內容,ObjectServiceConfigurationManager類通過調用AppObjectLocatorConfigurationManager.Current獲得Application.ObjectLocator信息,從而獲得ObjectServiceAgentName對應的配置代理名稱,再通過調用配置代理服務得到Service.xml的內容。如測試程式Service.xml的內容為:
<Application.ObjectService>
<Object name="A1" type="Test.Core.Service1,Test.Core">
<Property name="Service2" ref ="A2"/>
</Object>
<Object name="A2" type="Test.Core.Service2,Test.Core">
</Object>
<Object name="A3" type="Test.Core.Service3,Test.Core" isAspect="1">
</Object>
</Application.ObjectService>
有了獲得Service.xml的內容的前提,實際的類工廠/對象查找服務就是要實現這個介面:
public interface IObjectLocator:IDisposable
{
object GetObject(string objectName);
void FreeObject(string objectServiceName, object obj);
Type GetObjectType(string objectName);
bool IsSingleton(string objectName);
bool IsRemotingObject(string objectName);
bool IsCommunicationObject(string objectName);
}
具體實現這個介面的類正如<DefaultAppObjectLocatorService>Netop.Core.LocatorService.DefaultAppObjectLocatorService,Netop.Core</DefaultAppObjectLocatorService>所配置的為DefaultAppObjectLocatorService這個類,DefaultAppObjectLocatorService最重要的方法就是GetObject,這是獲得對象的方法,另一個FreeObject是釋放對象的方法。
做完了這些,統一由程式AppObjectLocatorManager提供給外部程式調用。
下麵分別從本地服務、遠程服務(NET Remoting)和WCF服務三個方面解說:
一、本地服務
本地服務還部分實現依賴註入(Dependency Injection)/控制反轉(Inversion of Control)的設值註入(value值註入和引用註入),為了微量化沒有做構造註入(理論上構造註入的事情也可以通過設值註入的方式相同的應用功能).
普通的本地服務配置為:
<Object name="A2" type="Test.Core.Service2,Test.Core">
</Object>
所有的配置都有name各type的設置。
上面配置為:名稱叫A2的Test.Core.Service2,Test.Core的類型服務,調用為:
IService2 s2 = Netop.Core.LocatorService.AppObjectLocatorManager.GetObject("A2") as IService2 ;
不使用時調用:Netop.Core.LocatorService.AppObjectLocatorManager.FreeObject("A2", s2);
配置還可增加服務是否單例(isSingleton),如 isSingleton的值為"true"或"1"或"yes",則為單例服務,否則為非單例服務。預設為非單例服務。
<Object name="A2" type="Test.Core.Service2,Test.Core" isSingleton="true">
</Object>
1.含有value值註入的本地服務
配置為:
<Object name="A" type="Netop.Test.A,Netop.Test" isSingleton = "true" >
<Property name="Code" value="2222"></Property>
</Object>
屬性Code在實例化時將被註入“2222”值.調用及isSingleton同普通的本地服務類似。
2.含有引用註入的本地服務
配置為:
<Object name="A1" type="Test.Core.Service1,Test.Core">
<Property name="Service2" ref ="A2"/>
</Object>
<Object name="A2" type="Test.Core.Service2,Test.Core">
</Object>
Service1屬性Service2是參照"A2"服務,實例化時將被註入. 調用及isSingleton同普通的本地服務一樣。
只有本地服務才可進行設值註入和isSingleton的設置。
二、遠程服務(NET Remoting)
NET Remoting是在WCF服務出現之前的極好的遠程服務,但在WCF服務出來之後便屬於淘汰技術,現留著主要是為了相容,而且為了那些原有NET Remoting程式而不願改寫為WCF服務的懶人們(當做是老闆考慮成本不願花時間花金錢呀)。
NET Remoting服務端的發佈和配置不提了,感興趣的朋友可以去查看相關資料。對於引用端(客戶端),用戶不用作其它什麼配置,除了要在Service.xml文件中配置:
<Object name="A1" type="Test2.Service1,Test2"
location="http://127.0.0.1:8989/Test2"
isClientActivated="true"></Object>
<Object name="A2" type="Test2.Service2,Test2" location="http://127.0.0.1:8989/Service2.rem" ></Object>
<Object name="A1IIS" type="Test2.Service1,Test2"
location="http://127.0.0.1/ROS"
isClientActivated="true"></Object>
<Object name="A2IIS" type="Test2.Service2,Test2" location="http://127.0.0.1/ROS /Service2.rem" ></Object>
即遠程服務要設置location,可選設置isClientActivated。location為伺服器端的位置(非IIS發佈還要含埠),isClientActivated="true"表示客戶端激活,否則為伺服器激活.
調用同普通的本地服務一樣.
遠程服務不可進行設值註入和isSingleton的設置,因為其實例化的本質就只是一代理對象而矣。
三、WCF服務
WCF服務的使用用較複雜一些,下麵舉例說明。對於WCF服務:
契約為:
namespace Contracts{
[ServiceContract(Name = "TestService", Namespace="http://www.Netop.com")]
public interface ITestService
{
[OperationContract]
string MyOperation1(string myValue);
}
}
實現為:
public class TestService : ITestService
{
public string MyOperation1(string myValue)
{ return "Hello: " + myValue; }
}
然後要做的是:
1、首先要實現一個繼承System.ServiceModel.ClientBase<T>的客戶端代理類
繼承System.ServiceModel.ClientBase<T>的客戶端代理類為:
namespace Test{
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class TestServiceClient : System.ServiceModel.ClientBase<ITestService>, ITestService
{
public TestServiceClient(){ }
public TestServiceClient(string endpointConfigurationName): base(endpointConfigurationName) { }
public TestServiceClient(string endpointConfigurationName,
string remoteAddress): base(endpointConfigurationName, remoteAddress) { }
public TestServiceClient(string endpointConfigurationName,
System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName,
remoteAddress) { }
public TestServiceClient(System.ServiceModel.Channels.Binding
binding, System.ServiceModel.EndpointAddress remoteAddress):
base(binding,
remoteAddress) { }
public string MyOperation1(string myValue)
{
return base.Channel.MyOperation1(myValue);
}
}
}
2、伺服器和客戶端該怎麼配置就還是怎麼配置(請參考有關WCF資料,在此不細說)
如在客戶端配置的是:
<system.serviceModel>
<client>
<endpoint address="http://127.0.0.1/Test/TestService.svc" binding="wsHttpBinding"
contract="Contracts.ITestService" name="TestService" />
</client>
</system.serviceModel>
3、在Service.xml的配置為:
<Object name="TestService1" type="Test.TestServiceClient,Test" communicationObjectEndpointName="TestService ">
</Object>
WCF服務要多設置communicationObjectEndpointName屬性。即:type的值為繼承System.ServiceModel.ClientBase<T>的客戶端代理對象的全名,communicationObjectEndpointName的值為客戶端配置的WCF服務名。
調用同普通的本地服務一樣.
Contracts.ITestService testService1 =
Netop.Core.LocatorService.AppObjectLocatorManager.GetObject("TestService1")
as Contracts.ITestService ;
不使用時一定要記得調用:Netop.Core.LocatorService.AppObjectLocatorManager.FreeObject("TestService1", testService1);
WCF服務不可進行設值註入和isSingleton的設置,因為其實例化的本質就只是一代理對象而矣。
總結一下:DefaultAppObjectLocatorService類實現了IObjectLocator介面,GetObject實現了本地服務、遠程服務(NET Remoting)和WCF服務的引用。本地服務還實現了依賴註入中的設值註入,當然還實現了AOP--下節將要談到的內容。不管上面所有的實現,最後的調用僅為GetObject和FreeObject,如下所示:
IService2 s2 = Netop.Core.LocatorService.AppObjectLocatorManager.GetObject("A2") as IService2 ;
...... //其它代碼
Netop.Core.LocatorService.AppObjectLocatorManager.FreeObject("A2", s2);
就是這麼簡單!
輕量級的.NET對象查找服務和AOP開發框架源碼Netop.Core3.5下載地址:http://download.csdn.NET/detail/tom_cat_xie_jxdy/9837303
輕量級的.NET對象查找服務和AOP開發框架測試源碼 下載地址:http://download.csdn.Net/detail/tom_cat_xie_jxdy/9837278
Netop.Core--輕量級的.NET對象查找服務和AOP開發框架文檔下載地址:http://download.csdn.net/detail/tom_cat_xie_jxdy/9838212