通過直接在命令 - 和查詢處理程序DbContext
依賴,我明白,我從StackOverflow user違反SOLID-principles因爲這樣評論的:使用的DbContext的SOLID方式
的
DbContext
是用布袋請求特定的運行時數據並將運行時數據注入構造函數會導致麻煩。讓你的 代碼直接依賴於DbContext
導致你的代碼 違反DIP和ISP,這使得難以維護。
這是完全有道理的,但我不確定如何解決它可能使用IoC和DI?
通過最初雖然是建立與可用於查詢的上下文中的單一方法的IUnitOfWork
:
public interface IUnitOfWork
{
IQueryable<T> Set<T>() where T : Entity;
}
internal sealed class EntityFrameworkUnitOfWork : IUnitOfWork
{
private readonly DbContext _context;
public EntityFrameworkUnitOfWork(DbContext context)
{
_context = context;
}
public IQueryable<T> Set<T>() where T : Entity
{
return _context.Set<T>();
}
}
現在,我可以在我的查詢處理程序取決於IUnitOfWork
(接收數據),我有解決了這部分。
接下來,我需要看一下我的命令(修改數據),我可以解決變化的節約與我的命令的裝飾背景:
internal sealed class TransactionCommandHandler<TCommand> : IHandleCommand<TCommand> where TCommand : ICommand
{
private readonly DbContext _context;
private readonly Func<IHandleCommand<TCommand>> _handlerFactory;
public TransactionCommandHandler(DbContext context, Func<IHandleCommand<TCommand>> handlerFactory)
{
_context = context;
_handlerFactory = handlerFactory;
}
public void Handle(TCommand command)
{
_handlerFactory().Handle(command);
_context.SaveChanges();
}
}
這工作得很好,以及。
第一個問題是:如何從我的命令處理程序修改上下文中的對象,因爲我不能直接依賴DbContext了?
像:context.Set<TEntity>().Add(entity);
據我瞭解我要創建另一個接口,這與固原則進行工作。例如,一個ICommandEntities
將包含像void Create<TEntity>(TEntity entity)
這樣的方法,更新,刪除,回滾甚至重新加載。然後依靠我的命令中的這個接口,但是我在這裏錯過了一個觀點,我們是否抽象得太深?
第二個問題是:這是在使用DbContext時尊重SOLID原則的唯一方式,還是這是違反原則的「可以」的地方?
如果需要,我使用Simple Injector作爲我的IoC容器。
您是否真的需要將DbContext抽象爲IUnitOfWork。即您是否可能用另一個ORM替換EF?如果沒有,爲什麼要介紹看似不必要的複雜性? –
您肯定有一個觀點 - 我可以看到這種方法的優點和缺點。 – janhartmann
我使用NHibernate並沒有計劃改變。我直接使用NHibernate Sessions進行事務管理等事情。但是,我傾向於傾向於存儲庫和查詢模式,以便單元測試更容易。 –