2

저는 AutoFac을 사용하여 웹 응용 프로그램에 구체적인 데이터 컨텍스트를 삽입하고 있습니다. 페이지에 예외가없는 경우 요청 끝에 데이터베이스 컨텍스트의 SaveChanges() 메서드를 실행하려고합니다. 그렇지 않으면 난 그냥 정상적으로 컨텍스트를 처분하고 싶다.AutoFac OnRelease를 사용하여 DbContext 변경 내용을 저장 하시겠습니까?

AutoFac에 OnRelease 메서드가 있음을 발견했습니다. 해당 메서드에 대한 Intellisense는 다음을 나타냅니다.

더 이상 필요없는 인스턴스를 처리하는 대신 제공된 작업을 실행하십시오.

builder.RegisterType<MyContext>().As<IDbContext>().InstancePerHttpRequest() 
    .OnRelease(x => { 
     if (HttpContext.Current != null && HttpContext.Current.Error == null) 
      x.SaveChanges(); 
     if (x != null) 
     { 
      x.Dispose(); 
      x = null; 
     } 
    }); 

이 데이터 컨텍스트에 대한 변경 사항을 적용 할 수있는 적절한 장소 : 이와 같이

,이 같은 일을 생각하고 있었는데? 예외가 발생하더라도 모든 요청에 ​​대해 실행되도록 보장됩니까?

답변

2

일반적으로 요청시 변경 사항을 저장할 때 유연성을 잃어 버리기 때문에 접근 방식이 마음에 들지 않습니다. 좋은 방법은 비즈니스 거래 종료시 변경 사항을 저장하는 것입니다. 이 샘플 코드 상상 :

public ActionResult CreateAccount(CreateAccountModel createAccountModel) 
{ 
    // Your business transaction start here from validating and processing input data 
    var account = CreateAccountFrom(createAccountModel); 
    _yourContext.Add(account); 
    // Your business transaction ends here 
    // This is the good place to commit your transaction 
    _yourContext.SaveChanges(); 

    // You can have another business transaction here 

    // the following is not important code to log the event 
    // which could break the business transaction if it would be within one 
    // you can wrap it in try-catch for example 
    _yourContext.Add(new Event(){ Type = AccountCreated }); 
    _yourContext.SaveChanges(); 

    // code to retrieve date for the view 
    var viewModel = GetViewModel(); 
    return View(viewModel); 
} 


지금 한마디로, 코드에 대한를, 그 변경 사항을 저장하는 나쁜 장소입니다. 우선 당신은 Single Responsibility 원칙을 위반합니다. OnRelease는 IDisposable없이 클래스의 리소스를 정리하지만 추가 로직을 수행하지 않아야합니다. 비즈니스 로직을 할 수 있기 때문에 거기에 놓는 것은 좋지 않습니다. 두 번째로, x.SaveChanges()에 예외가 발생하면 컨텍스트가 삭제되지 않습니다. 비즈니스 로직 및 객체 수명 논리를 엉망으로 처리하지 않는 것이 좋습니다.

+0

Alexandr, 답변 해 주셔서 감사합니다. 필요한 경우 내 코드 내에서 SaveChanges()를 호출 할 수있는 유연성이 있습니다. 또한 처분에 대한 걱정을 처리하기 위해 나머지 코드에서와 마찬가지로 try/catch/finally 블록에'SaveChanges()'를 래핑 할 수 없습니까? – Sam

+1

@Sam "필요한 경우 내 코드 내에서 SaveChanges()를 호출 할 수있는 유연성이 있습니다." 왜이 두 가지 방법을 결합하고 싶습니까? 버그로 연결됩니다. "try/catch/finally 블록에서 SaveChanges()를 래핑 할 수 없습니다."예, 작동하지만 ... :) –

관련 문제