2017-10-28 3 views
1

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가 여전히있을 수 있습니다.

+0

그것은 예외와 함께 어떻게됩니까 ... 당신이 그것을 처리하지 않으면 사용자가 500 오류 (나는 당신이 요청 asp.net이라고 가정)를 얻을 것이다. 이를 처리하고 요청이 계속되면 동일한 dbcontext 인스턴스에 대한 savechanges 호출이 동일한 예외를 생성합니다. – Igor

+0

나는 더 명확하게하기 위해 나의 포스트를 편집했다. – JeloneK

+1

@JeloneK'DbContext'는 * Unit Of Work * 패턴의 구현입니다. 당신이했던 것처럼 다른 작업 단위로 다시 감싸는 것은별로 의미가 없습니다. 추가 래퍼는 아무런 도움이되지 않습니다. – Kostya

답변

-1

는 @Igor는 처리 여부를 그 예외가 차이를 만드는,하지만 시나리오는 동일한 요청에 anothet 저장소를 호출 포함, 나는 당신이 그것을 처리 않았다 가정합니다 여부, 코멘트에 말했듯이.

DbContextFactory의 동일한 인스턴스를 다시 사용하고 DbContext 인스턴스를 보유한 사람이 다시 말했듯이, 해당 팩토리를 다른 곳에 배치하지 않으면 컨텍스트에 여전히 사용자가 추가 된 동일한 인스턴스가 추가됩니다 따라서 anothet 저장소에서 같은 컨텍스트에 대해 Commit을 호출하면 여전히 해당 사용자가 삽입됩니다.