DbContext를 얻기 위해 저장소에 사용하는 DbContextFactory를 가정 해 봅시다. (최선의 해결책인지는 확실하지 않습니다).DbContext 처분, dbcontext 팩토리, 작업 단위
public class DbContextFactory : Disposable, IDbContextFactory
{
private readonly Dictionary<Type, System.Data.Entity.DbContext> _dbContexts;
public DbContextFactory()
{
_dbContexts = new Dictionary<Type, System.Data.Entity.DbContext>();
}
public T GetDbContext<T>() where T : System.Data.Entity.DbContext, new()
{
if (!_dbContexts.ContainsKey(typeof(T)))
{
_dbContexts.Add(typeof(T), new T());
}
return _dbContexts[typeof(T)] as T;
}
protected override void DisposeCore()
{
foreach (var kvpDbContext in _dbContexts)
{
kvpDbContext.Value?.Dispose();
}
}
}
그리고 나는 내가 저장소 메소드를 호출보다 BusinessLogic 클래스
public class UnitOfWork<T> : IUnitOfWork
where T : System.Data.Entity.DbContext, new()
{
private readonly IDbContextFactory _dbContextFactory;
private T _dbContext;
public UnitOfWork(IDbContextFactory dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
public T DbContext => _dbContext ?? (_dbContext = _dbContextFactory.GetDbContext<T>());
public void Commit()
{
DbContext.SaveChanges();
}
}
에 주입하고, 현실을 가정 해 봅시다 UnitOfWork에이 예외가 발생합니다 : 내가 전화하면 무슨 일이 생긴 것
public void CreateUser(User user)
{
_userRepository.Add(user);
throw new Exception();
UnitOfWork.Commit();
}
같은 리퀘스트의 다른 리포지터리 메소드 (또는, 단지 request-per-request로서 factory를 사용하지 말아주세요).이 메소드는 정상적으로 종료 해, UnitOfWork.Commit()가 불려가 변경을 의미합니다 실패한 CreateUser 메소드에서 작성된 내용도 역시 저장됩니까? 또는 연결을 닫을 때 예외가 발생하고 위험이 없으면 해당 메서드의 변경 사항이 저장됩니다.
더 명확하게하려면 : WCF 서비스에서이를 호스트하고 싶습니다. 싱글 톤 모드로 가정 해 봅시다. 그리고 여러 개의 (예를 들어 5 개) 저장소 호출을 포함하는 하나의 요청 호출 메소드와 처음 세 개는 성공하고 네 번째는 실패합니다. 즉, UnitOfWork.Commit()을 호출하지 않을 것입니다. 그리고 다른 요청이오고, 그것은 단지 성공입니다. 이전의 방법으로 호출 한 처음 세 저장소의 변경 사항이 저장된다는 의미입니까? 싱글 톤 때문에 동일한 DbContextFactory에 동일한 DbContext가 여전히있을 수 있습니다.
그것은 예외와 함께 어떻게됩니까 ... 당신이 그것을 처리하지 않으면 사용자가 500 오류 (나는 당신이 요청 asp.net이라고 가정)를 얻을 것이다. 이를 처리하고 요청이 계속되면 동일한 dbcontext 인스턴스에 대한 savechanges 호출이 동일한 예외를 생성합니다. – Igor
나는 더 명확하게하기 위해 나의 포스트를 편집했다. – JeloneK
@JeloneK'DbContext'는 * Unit Of Work * 패턴의 구현입니다. 당신이했던 것처럼 다른 작업 단위로 다시 감싸는 것은별로 의미가 없습니다. 추가 래퍼는 아무런 도움이되지 않습니다. – Kostya