2016-03-15 69 views
0

我正在開發一個應用程序,允許用戶將電影從一個位置複製到他們的用戶帳戶。爲此,電影將需要被複制到用戶的個人文件夾。域驅動設計和文件存儲

我面臨的問題是,實際上覆制文件。目前,我有一個MovieFactory,在創建後,在工廠方法完成複製後立即將其放入MovieRepository中。這似乎工作正常。

然而,存儲庫和工廠不必知道彼此。理想情況下,我會做這樣的:

var movie = this.MovieFactory.CreateFromFile(new FileInfo("MyPhoto.mp4")); 
this.MovieRepository.Add(movie); 

現在我的想法是做Add方法內的複製,因爲你基本上覆制到庫本身。但是,通過這樣做,電影的文件位置也會改變。因此,Add方法必須修改movie或返回一個新的但不同的影片實例。這聽起來像代碼味道給我,我完全卡在這種情況。

在說話時,文件位置不會被存儲。而是使用MovieFileLocator服務從多個其他電影屬性中推導出位置。

回答

2

由於問題有DDD標籤,我會更DDD術語回答:

  • 您使用工廠CreateFromFile方法
  • 這裏面工廠方法你絕對調用一些構造函數創建一個Movie聚集和/或的Movie
  • 方法可以派遣域事件MovieCreatedFromFile並在處理程序做任何你想做的事情(複製文件到用戶的文件夾)
  • 您繼續通過添加彙總到資源庫

究竟如何域事件調度和處理工作將在應用服務方法流程 - 這是你的。由於這是與基礎設施相關的工作,因此我會將其派往當前工作單元之外。您可以使用像Hangfire這樣的輕量級設備。通過這個你可以確保你的聚合是事務邊界,但是當它(不太可能)發生時,準備處理文件複製錯誤。這種「準備」可能只包括通知和手工工作,因爲它可能永遠不會發生。

0

所以位置取決於電影的幾個屬性。你想移動電影,這意味着你想修改電影的屬性。我想你應該複製。像MovieRepository.Add(電影); movie.LocationProperty = Locations.NewLocation(在這裏你將做文件的實際移動)

+0

考慮到你抽象的位置,複製本身可能變得沒有必要,因爲物理位置可能變得無關緊要,並且隻影響電影的屬性。 –

+0

然而,問題在於位置取決於電影是否實際存儲在存儲庫中。如果已放入,位置指向用戶文件夾中的某個位置。如果它不在存儲庫中,則該位置仍然是USB驅動器的原始源。 – Shammah

+0

因此,只需將該項目添加到存儲庫即可更改該項目,這是困擾您並帶來代碼異味的原因。在我看來,這正是你應該改變的。但是,如果您將其視爲兩種不同類型的電影類,比如說OriginalContent和ImportedMovie,那麼像「ImportedMovie movie = repo.Import(OriginalContent)」這樣的操作會很有意義,因爲原始類和最終導入的電影。這可能也解決了即時更改屬性的問題,然後必須等待幾秒鐘才能複製文件。 –

0

你有兩個對象位於應用程序層。如果我理解正確,通過複製意味着爲用戶分配電影的領域邏輯。

在這種情況下,您應該爲接受電影和用戶的過程創建域服務。這個域名服務應該注入一個帶有處理電影操作接口的對象,並調用類似movie.assignTo(user.id)的東西。通過這種方式,您可以明確地分析並分離域邏輯與基礎架構邏輯。