我对DDD中的工厂、存储库和服务有一些疑问。我有以下实体:文件夹、文件、FileData。
在我看来,“文件夹”是一个聚合根,应该负责创建 File 和 FileData 对象。
所以我的第一个问题是我应该使用工厂来创建这个聚合还是由存储库决定?此时我有 2 个存储库,一个用于文件夹,另一个用于文件,但在我看来,我应该将它们合并在一起。以下代码片段显示了我的Folder Repository,它位于我的基础设施层中:
public class FolderRepository : IFolderRepository
{
#region Fields
private readonly IFolderContext _context;
private readonly IUnitOfWork _unitOfWork;
#endregion
#region Constructor
public FolderRepository(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_context = _unitOfWork.Context as IFolderContext;
}
#endregion
public IUnitOfWork UnitOfWork
{
get { return _unitOfWork; }
}
public IQueryable<Folder> All
{
get { return _context.Folders; }
}
public Folder Find(Guid id)
{
return _context.Folders.Find(id);
}
public void InsertGraph(Folder entity)
{
_context.Folders.Add(entity);
}
public void InsertOrUpdate(Folder entity)
{
if (entity.Id == Guid.Empty)
{
_context.SetAdd(entity);
}
else
{
_context.SetModified(entity);
}
}
public bool Delete(Guid id)
{
var folder = this.Find(id) ?? _context.Folders.Find(id);
_context.Folders.Remove(folder);
return folder == null;
}
public int AmountOfFilesIncluded(Folder folder)
{
throw new NotImplementedException();
//return folder.Files.Count();
}
public void Dispose()
{
_context.Dispose();
}
}
接下来我在我的应用层创建了一个服务,称为“IoService”。我对服务的位置有疑问。是否应该将其移至域层?
public class IoService : IIoService
{
#region Fields
private readonly IFolderRepository _folderRepository;
private readonly IFileRepository _fileRepository;
private readonly IUserReferenceRepository _userReferenceRepository;
#endregion
#region Constructor
public IoService(IFolderRepository folderRepository, IFileRepository fileRepository, IUserReferenceRepository userReferenceRepository)
{
if(folderRepository == null)
throw new NullReferenceException("folderRepository");
if(fileRepository == null)
throw new NullReferenceException("fileRepository");
if (userReferenceRepository == null)
throw new NullReferenceException("userReferenceRepository");
_folderRepository = folderRepository;
_fileRepository = fileRepository;
_userReferenceRepository = userReferenceRepository;
}
#endregion
#region Folder Methods
/// <summary>
/// Create a new 'Folder'
/// </summary>
/// <param name="userReference"></param>
/// <param name="name"></param>
/// <param name="parentFolder"></param>
/// <param name="userIds">The given users represent who have access to the folder</param>
/// <param name="keywords"></param>
/// <param name="share"></param>
public void AddFolder(UserReference userReference, string name, Folder parentFolder = null, IList<Guid> userIds = null, IEnumerable<string> keywords = null, bool share = false)
{
var userReferenceList = new List<UserReference> { userReference };
if (userIds != null && userIds.Any())
{
userReferenceList.AddRange(userIds.Select(id => _userReferenceRepository.Find(id)));
}
var folder = new Folder
{
Name = name,
ParentFolder = parentFolder,
Shared = share,
Deleted = false,
CreatedBy = userReference,
UserReferences = userReferenceList
};
if (keywords != null)
{
folder.Keywords = keywords.Select(keyword =>
new Keyword
{
Folder = folder,
Type = "web",
Value = keyword,
}).ToList();
}
//insert into repository
_folderRepository.InsertOrUpdate(folder);
//save
_folderRepository.UnitOfWork.Save();
}
/// <summary>
/// Get 'Folder' by it's id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Folder GetFolder(Guid id)
{
return _folderRepository.Find(id);
}
#endregion
#region File Methods
/// <summary>
/// Add a new 'File'
/// </summary>
/// <param name="userReference"></param>
/// <param name="folder"></param>
/// <param name="data"></param>
/// <param name="name"></param>
/// <param name="title"></param>
/// <param name="keywords"></param>
/// <param name="shared"></param>
public void AddFile(UserReference userReference, Folder folder, FileData data, string name, string title = "", IEnumerable<string> keywords = null, bool shared = false)
{
var file = new File
{
Name = name,
Folder = folder,
FileData = data,
CreatedBy = userReference,
Type = data.Type
};
if (keywords != null)
{
file.Keywords = keywords.Select(keyword =>
new Keyword
{
File = file,
Type = "web",
Value = keyword,
}).ToList();
}
folder.Files.Add(file);
folder.Updated = DateTime.UtcNow;
_folderRepository.InsertOrUpdate(folder);
//save
_folderRepository.UnitOfWork.Save();
}
/// <summary>
/// Get 'File' by it's id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public File GetFile(Guid id)
{
return _fileRepository.Find(id);
}
#endregion
}
总结一下:我是否应该使用该服务来创建文件夹对象。或者服务应该只使用一个工厂,它负责创建对象并将创建的对象发送到存储库?那么服务中的依赖注入呢,我应该从 UI 层使用Unity等 IOC 容器注入我的服务,还是应该只对服务中的依赖项进行硬编码?
谢谢