24

MVC 응용 프로그램에 대한 DbContext/POCO 모델을 생성하기 위해 Entity Framework 데이터베이스 우선 접근 방식을 사용합니다. 내 컨트롤러의 DbContext에 대한 종속성을 피하여 (예 : 단위 테스트 목적으로) 필자가 필요로하는 다른 퍼시스턴스 공급자로 전환 할 수있게하고 싶습니다.Castle Windsor에서 Entity Framework 사용

이렇게하려면 Castle Windsor IoC 컨테이너를 사용하고 싶습니다. DbContext를 IUnitOfWork 서비스로 등록하고 일반 IRepository 서비스를 등록 할 계획입니다.이 서비스는 모델의 집계 루트에 액세스하여 작업하는 데 사용할 구현입니다.

나는 윈저에 새로 온 사람과 EF와 함께 사용하는 방법에 대한 많은 정보를 찾을 수 없어, 나는 몇 가지 질문이 있습니다 내가 분리하려는 경우

  • 이 합리적인 방법입니다 응용 프로그램에서 EF?
  • IUnitOfWork 및 일반 IRepository 서비스를 어떻게 설치/등록합니까?
+3

누구든지이 아래로 표시 ... 당신은 왜 말 코멘트를 제공 하시겠습니까? 내가 어딘가에서 그 요점을 놓쳤다 고 생각한다면, 당신은 왜 그 이유를 설명함으로써 나를 도울지도 모른다. –

+0

이 질문은 투표의의 미결이라고 생각합니다. StackOverflow, 특히 첫 번째 지점에는 적절하지 않습니다. 두 번째 요점은 캐슬 윈저 (Castle Windsor) 사이트에서 찾을 수 있습니다. 훌륭한 문서가 있습니다. 귀하의 질문 내용 : 단위 테스트를위한 DbContext 조롱은 사실상 불가능합니다 (http://stackoverflow.com/a/13352779/861716). 나는 다른 BL에 대한 순수한 단위 테스트 프로젝트 외에 DAL 테스트를위한 데이터베이스에 대해 '단위 테스트'프로젝트를 사용합니다. Caste Windsor는 인터페이스가 아닌 컨텍스트 팩토리에서 컨텍스트를 주입하고 인터페이스 서비스, 유효성 검사기 등을 입력합니다. –

+0

@GertArnold에게 감사드립니다. 조롱 문제와 관련하여 DAL을 단위 테스트하고 싶지는 않지만 응용 프로그램 계층 (예 : 컨트롤러)에 모의 리포지토리를 제공하여 테스트 할 수 있습니다. 성 문서는 일반적으로 훌륭하지만 NHibernate 통합을 다룬다. 그리고 그 영역에서는 꽤 스케치된다. –

답변

25

그래서 결론을 내렸다. 난 다른 사람이/단위 테스트 EF, 윈저와 MVC를 함께 사용하려고하는 경우 사용하기 위해이 글을 쓸 줄 알았는데.

우선, DbContext는 저장소 및 작업 단위 패턴을 모두 구현하므로 이러한 구현이 제공되는지 또는 직접 생성해야하는지 여부를 확인해야합니다.

집계 루트 당 하나씩, DDD 패턴에 따라 자체 저장소를 만들기로했습니다. 그 이유는 쿼리 코드를 캡슐화하여 응용 프로그램 계층으로 유출되는 것을 방지하고 응용 프로그램 컨트롤러를 테스트 할 때 더 쉽게 모의 할 수 있기 때문입니다. IRepository<TEntity>을 기반으로 일반 저장소를 만들었습니다. 거기에 많은 예제가 있습니다. 이 좋은 것을 찾았습니다. http://architects.dzone.com/articles/implementing-repository

한편 IUnitOfWork 서비스를 삭제하고 대신 기본 구현을 선택했습니다. 그러나 IDbContext 추상화 (Microsoft가이 작업을 직접 수행하지 않은 이유를 모름)를 작성하여 리포지토리 서비스를 테스트 할 때 DbContext를 조롱했습니다.

IDbContext에 저장소에서 사용하려는 DbContext 멤버 만 제공했습니다.그래서 :

public interface IDbContext: IDisposable 
{ 
    Database Database { get; } 
    DbEntityEntry Entry(object entity); 
    IDbSet<TEntity> Set<TEntity>() where TEntity : class; 
    int SaveChanges(); 
} 

내가 다음 내 IDbContext 및 IRepository 서비스에 대한 윈저 시설 및 설치 프로그램을 만들어 :

public class EntityFrameworkFacility: AbstractFacility 
{ 
    protected override void Init() 
    { 
     Kernel.Register(Component.For<IDbContext>() 
           .ImplementedBy<MyEntities>() 
           .LifestylePerWebRequest(), 
         Component.For(typeof(IRepository<>)) 
           .ImplementedBy(typeof(Repository<>)) 
           .LifestylePerWebRequest()); 
    } 
} 

public class PersistenceInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.AddFacility<EntityFrameworkFacility>(); 
    } 
} 

마지막 조각은 IDbContext을 구현하기 위해 엔티티 프레임 워크 컨텍스트 클래스를 확장하고, 그림자했다 세트() 메소드는 오히려 DbSet보다 IDbSet을 반환 :

public partial class MyEntities : IDbContext 
{ 
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class 
    { 
     return base.Set<TEntity>(); 
    } 
} 
곳에서 이에

(및 윈저 문서에 도시 ControllerFactory 등록)을 저장소 단위 테스트

public ControllerBase(IRepository<Contact> repo) 
{ 
    _repo = repo; 
} 

실제 저장소 인스턴스 모의 IDbContext으로 백업 할 수 :

mocks = new MockRepository(); 
context = mocks.StrictMock<IDbContext>(); 
repo = new Repository<Contact>(context); 
을 필요 윈저 제어기 생성자로 IRepository 개체 (또는 IDbContext)을 주입받을 단순해진다 컨트롤러 유닛 테스트에서

는 모의 저장소를 사용할 수 있습니다

mocks = new MockRepository(); 
repo = mocks.StrictMock<IRepository<Contact>>(); 
ContactController controller = new ContactController(repo); 
+2

샘플 코드를 제공하고 시간을내어 주셔서 감사합니다 .-) –

+1

MyEntities가 DbContext를 확장해야합니다. – SoWeLie

+0

실제로 Entity Framework에서 생성 된 컨텍스트 클래스는 DbContext에서 상속합니다.이 클래스는 IDbContext를 지원하기 위해 해당 클래스를 확장하는 부분 클래스입니다. –

관련 문제