asp.net mvc를 사용하여 다중 테넌트 앱에서 작업 중입니다. 각 요청에 대해 테넌트를 식별해야하므로 아래에 클래스를 만들었습니다.
public class TenantProvider
{
public static Tenant Tenant
{
get
{
Tenant tenant = HttpContext.Current.Items["Tenant"] as Tenant;
if (tenant == null)
{
var tenantUsername = HelperUtility.GetCurrentRequestHost();
//The below line of code is my problem
TenantRepository tenantRepository = new TenantRepository(new AppointContext());
tenant = tenantRepository.GetByUsername(tenantUsername);
HttpContext.Current.Items.Add("Tenant", tenant);
}
return tenant;
}
}
}
현재 요청에 대한 테넌트를 반환하는이 클래스 정적 속성입니다. 먼저 데이터베이스에서 테넌트를 가져오고 캐시를 초기화하고 테넌트를 반환하는 것보다 찾을 수없는 경우 캐시의 테넌트를 먼저 확인합니다.
Tenant에서 데이터베이스를 얻기 위해 TenantRepository 인스턴스를 만들고 있습니다. TenantRepository는 인스턴스를 생성하는 동안 전달하는 데이터베이스 컨텍스트에 대한 종속성이 있습니다.
이제 현재 테넌트에서 다른 데이터베이스 작업을 수행해야 할 때 다른 장소에서 새 리포지토리 인스턴스를 만들고 새 컨텍스트를 전달해야하므로 테넌트를 추출한 실제 컨텍스트와 새 컨텍스트가 다릅니다. 문제를 일으킬 수 있다고 생각합니다.
그래서 내 질문은이 시나리오를 어떻게 처리 할 수 있습니까? 그러면 동일한 컨텍스트 인스턴스가 사용됩니다.
찾고있는 솔루션은 작업 단위 (UOW) 디자인 패턴입니다. Martin Fowler에서 :
비즈니스 트랜잭션의 영향을받는 개체 목록을 유지하고 변경 내용 작성 및 동시성 문제 해결을 조정합니다.
참조 : http://martinfowler.com/eaaCatalog/unitOfWork.html
이 패턴을 사용하면 여러 트랜잭션을 단일 컨텍스트에 등록 할 수 있습니다. 이것은 매우 일반적인 패턴이며 여기에 가능한 구현이 있습니다. 먼저 중앙 컨텍스트에 대한 참조를 보유하고 해당 컨텍스트로 리포지토리를 초기화 할 작업 단위 개체를 만듭니다 (이 구현에서는 Entity Framework를 사용함).
public class UnitOfWork : IUnitOfWork
{
internal EntitiesContext _context = new EntitiesContext ();
private ITenantRepository _tenantRepository;
private IOtherRepository _otherRepository;
public ITenantRepository TenantRepository
{
get
{
if (_tenantRepository== null)
{
_tenantRepository= new TenantRepository(_context);
}
return _tenantRepository;
}
}
public IOtherRepository OtherRepository
{
get
{
if (_otherRepository== null)
{
_otherRepository= new OtherRepository(_context);
}
return _otherRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
이 패턴이있는 저장소를 사용하는 경우 모두 동일한 컨텍스트를 사용합니다.
컨트롤러는 작업 단위를 초기화하거나 더 나은 방법으로 생성자에 주입해야합니다.
public TenantController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_tenantRepository = unitOfWork.TenantRepository;
_otherRepository = unitOfWork.OtherRepository;
}
UnitOfWork를 다른 레이어에 사용해야하는 경우 일반적으로 다른 개체의 생성자에 인수로 전달합니다.
public ActionResult Index()
{
TenantProvider provider = new TenantProvider(_unitOfWork);
_otherRepository.DoWork();
_unitOfWork.Save();
}
이제 TenantProvider
각각의 저장소로 작업을 수행 할 수 있지만 작업 단위 OtherRepository
는 동일한 컨텍스트를 사용하여 작업을 수행 할 수도 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다