我目前正在重構ASP.NET MVC項目以使用onion arcitecture,因爲它似乎適合未來開發的需要。在洋蔥架構中放置視圖模型/ DTO
我已成立了,我想我需要使用層和我的解決方案,現在看起來是這樣的:
所以,基本上我已經瞭解,ClientName.Core
項目應該不會有什麼參考其他項目。 ClientName.Infrastructure
應該有對ClientName.Core
的引用。 ClientName.Core
上的Interfaces文件夾定義了ClientName.Infrastructure
項目中的服務,並且我的DbContext和域實體是分開的,因此只有實體位於核心項目中。
我把頭靠在牆上的地方是,ClientName.Infrastructure
項目不應該將域實體返回到調用它的任何客戶端。這將在覈心項目和任何「違反」洋蔥原則的用戶界面之間創建一個參考。正如我所讀到的,解決這個問題的方法是讓基礎架構服務返回DTO。但是,如果我要返回的類別是PersonService
類中的PersonDto
,則需要ClientName.Core
項目知道PersonDto
對象,因爲這是該接口所在的位置。
所以問題是:我究竟在哪裏放置用於UI /客戶端的DTO/ViewModel /其他模型?我是否創建了一個單獨的類庫來保存這些模型,並讓UI,基礎結構和核心項目都引用它?
任何幫助/提示,我有點困惑提前這個;-)
由於是極大的讚賞。
編輯
基於Euphorics答案,我寫了示例代碼這裏只是爲了檢查,如果我有一些跟進的問題得到它的權利和可能。
所以基本上,我ClientName.Core
層,我有我的實體包含業務邏輯,即Person
和Firm
實體看起來是這樣的:
(Exists in ClientName.Core/Entities)
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Firm Firm { get; set; }
}
(Exists in ClientName.Core/Entities)
Public class Firm
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Person> Employees { get; set; }
public IEnumerable<Person> GetEmployeesByName(string name)
{
return Employees.Where(x => x.Name.Equals(name));
}
public void AddEmployee(Person employee)
{
Employees.Add(employee);
}
public void CreateFirm(Firm firm)
{
// what should happen here? Using entity framework, I have no reference to the DbContext here...
}
}
(Exists in ClientName.Infrastructure/Services)
public class FirmService : IFirmService
{
private readonly IDbContext _context;
public FirmService(IDbContext context)
{
_context = context;
}
public Firm GetById(int firmId)
{
return _context.Firms.Find(firmId);
}
// So basically, this should not call any domain business logic?
public void CreateFirm(CreateFirmFormViewModel formViewModel)
{
Firm firm = new Firm()
{
Name = formViewModel.Name;
}
_context.Firms.Add(firm);
_context.SaveChanges();
}
public IEnumerable<Person> GetEmployeesByName(int firmId, string name)
{
Firm firm = _context.Firms.Find(firmId);
return firm.GetEmployeesByName(name);
}
}
我是正確,每一個讀查詢應該是直接在實體上定義(可能作爲實體擴展,因爲我使用實體框架),並且任何創建/更新/刪除只會發生在基礎設施層的服務中?
讀取(即IEnumerable<Person> GetEmployeesByName(int firmId, string name)
方法)方法是否也在FirmService
接口/類上?
再次感謝:-)
嗨@Euphoric,謝謝你的回答。我剛剛用一些簡單的代碼和一些後續問題更新了我的問題,只是爲了確保我理解正確。 –