我正在開發一個WCF項目,我想實現一個RICH域模型,客戶端對象充當服務器端功能的遠程外觀但與客戶端/服務器之間的某些共享方面,如驗證。比方說,我有兩個方法的Order類:Save()和Submit()。在服務器上,Save()方法將寫入數據庫,並且Submit()會將訂單發送給供應商的系統。在客戶端對象充當遠程外牆的WCF中實現豐富的域模型
我想在客戶端上鏡像豐富的域模型,但不想在Save()方法中寫入數據庫,我想運行驗證碼,然後在WCF服務接口上調用SaveOrder(this)。這將遵循Fowler的服務層+域模型模式。理想情況下,我想編寫AbstractOrder基類,實現所有共享功能並指定抽象函數,然後實現充當服務服務器的ClientOrder,ServerOrder和WCF接口IOrderService(具有Save(AbstractOrder)和Submit(AbstractOrder)) -側。 ClientOrder的Save()/ Submit()會調用IOrderService上的保存/提交方法,並在方法調用期間傳遞它自己。
有沒有辦法指示WCF哪些對象實例化和反序列化內容?我特別想在整個應用程序中使用對象的抽象版本,只有在反序列化時才能確定我是否需要客戶端/服務器端版本的對象?我們已經定製了WCF通信渠道:我們使用protobuf和gzip壓縮技術來實現客戶端/服務器和Ninject之間的數據傳輸以實現服務實例化。理想情況下,我想將對象實例化卸載到Ninject。
我特別不希望訂單類是一個WCF服務,因爲我正在處理一個相當胖的客戶端,其中需要大量的邏輯來保持系統在設定的限制內執行,我最好不要想要結束一個貧血的領域模型,其中大多數邏輯被塞進服務中。
在代碼中它會是這樣的:
[ServiceContract]
public interface IOrderService
{
[OperationContract]
AbstractOrder GetById(int id);
[OperationContract]
IEnumerable<AbstractOrder> GetBySupplier(int supplierId);
[OperationContract]
void Save(AbstractOrder order);
[OperationContract]
void Submit(AbstractOrder order);
}
public abstract class AbstractOrder()
{
public int Id { get; set; }
public string Description { get; set; }
public List<AbstractOrderline> OrderLines { get; set; }
public abstract void Save();
public abstract void Submit();
}
public class ClientOrder : AbstractOrder
{
public override void Save()
{
ValidateOrThrow();
_service.Save(this);
}
public override void Submit()
{
ValidateOrThrow();
_service.Submit(this);
}
}
public class ServerOrder : AbstractOrder
{
public override void Save()
{
ValidateOrThrow();
_unitOfWork.Save(this);
}
public override void Submit()
{
Save();
_supplierOrderService.Submit(this);
}
}
您有五個段落開頭的一,無論如何,如果你想分享的WCF服務和CLIEN之間DTO類型t,它們在整個調用堆棧中的類型完全相同。您可以隨時在該Order類中引入IOrderService,並通過屬性設置IOrderService。在服務器上實現它的類將寫入數據庫或調用其他服務,您在客戶端上設置的服務將調用WCF服務。 – CodeCaster
問題是,我不想將域模型轉換爲DTO,然後再轉換回客戶端上的域模型。福勒特別寫道,在當地環境中使用DTO可能有害,並且使API更難使用(http://martinfowler.com/bliki/LocalDTO.html)。 這個想法是將ServerOrder傳輸到客戶端,並將其反序列化爲ClientOrder實例。我們使用protobuf進行(反)序列化,所以我目前正在考慮是否有可能影響在反序列化期間創建哪個對象,有可能通過將其重新引導至Ninject。 – Toolmaker
我知道WCF的邊界意味着'偏遠',但因爲我們的客戶/服務器應用程序共享大量代碼,我們認爲它們之間的通信是本地的。 – Toolmaker