1

맨손으로 여기에 많은 코드가 있기 때문에 맨손으로. 내가 쫓고있는 목표는 공장이 관련된 여러 클래스간에 내 EF 컨텍스트를 공유 할 수있게하는 것입니다. 요청 당 바인딩에 대해 알고 있지만 웹 요청 당 여러 작업 단위 사용 문제를 해결할 수 없으므로이를 피하려고합니다.Ninject 바인딩/보존 컨텍스트/IRepository/작업 단위

사용 예 : 여기

using (var uow = this.uowFactory.Create()) 
    { 
     return uow.CampusRepository.Get().ToList(); 
    } 

여기

Class diagram

저장소 공장 인터페이스입니다 설명하기위한 도면 :

public interface IRepositoryFactory 
{ 
    IRepository<TEntity> CreateGenericRepository<TEntity>() where TEntity : class; 

    TInterface CreateCustomRepository<TInterface>() where TInterface : class; 
} 

따라서 워크 플로우는 것 같은 뭔가 :

    나는 uowFactory (IInventoryUOWFactory)을 사용하십시오 using 문 작업 단위 (추상적 인 InventoryUOW의 구현)

    public interface IInventoryUowFactory 
    { 
        InventoryUOW Create(); 
    } 
    
  • EF_UOW이 InventoryUOW을 구현하고, 즉 있도록이 그것에 바인딩을 만들 수있는 내부

  • 무엇 InventoryUOW의 생성자가

    public class EF_UOW : InventoryUOW 
    { 
        private readonly InventoryContext context; 
        public EF_UOW(IRepositoryFactory factory, InventoryContext context) 
         : base(factory) 
        { 
         if (context == null) 
         { 
          throw new ArgumentNullException("context"); 
         } 
         this.context = context; 
        } 
        public override int Save() 
        { 
         return context.SaveChanges(); 
        } 
    
        public override void Dispose() 
        { 
         context.Dispose(); 
        } 
    } 
    
    
    public abstract class InventoryUOW : UnitOfWork 
    { 
        private readonly IUserRepository userRepository; 
        private readonly IRepository<Campus> campusRepository; 
    
    
        protected InventoryUOW(IRepositoryFactory repoFactory):base(repoFactory) 
        { 
         this.userRepository = GetCustomRepository<IUserRepository>(); 
         this.campusRepository = GetGenericRepository<Campus>(); 
        } 
        public virtual IUserRepository UserRepository 
        { 
         get 
         { 
          return this.userRepository; 
         } 
        } 
    
        public virtual IRepository<Campus> CampusRepository 
        { 
         get 
         { 
          return this.campusRepository; 
         } 
        } 
    } 
    

    을 실행에 호출 후 생성되고 알 수있는 바와 같이의 UnitOfWork의 생성자가 먼저 실행

    public abstract class UnitOfWork : IDisposable 
    { 
        protected readonly IRepositoryFactory factory; 
        public UnitOfWork(IRepositoryFactory factory) 
        { 
         if (factory == null) 
         { 
          throw new ArgumentNullException("factory"); 
         } 
         this.factory = factory; 
        } 
        protected IRepository<T> GetGenericRepository<T>() where T : class 
        { 
         return factory.CreateGenericRepository<T>(); 
        } 
    
        protected T GetCustomRepository<T>() where T : class 
        { 
         return factory.CreateCustomRepository<T>(); 
        } 
    
        public abstract int Save(); 
        public abstract void Dispose(); 
    } 
    
  • 이제이 public EF_UOW(IRepositoryFactory factory, InventoryContext context)은 IRepositoryFactory를 팩터 리 kernel.Bind<IRepositoryFactory>().ToFactory()으로 해석하고이 팩토리는 GetCustomRepository 및 GetGenericRepository를 호출 할 때 InventoryUOW 생성자에서 사용됩니다. 또한 DbContext의 하위 클래스 인 InventoryContext는 EF_UOW 수준에서 확인됩니다.

  • 설명한대로 IRepositoryFactory를 사용하면 리포지토리 개체가 만들어집니다 (나중에 설명 할 Ninject 바인딩에 따라 다름). 하나의 해상도는, 내 경우에는 (바인딩에 따라) DbContext의 하위 클래스를받는 concreate Repository 클래스

    public Repository(DbContext context) 
    { 
    
        this.context = context; 
        this.dbSet = context.Set<TEntity>(); 
    } 
    

이제 문제는 내가 동일한 컨텍스트를 사용하고자하는 것입니다 이어질 것

 const string scopeName = "DbContext"; 
     kernel.Bind<AccountManagementController>().ToSelf(); 
     kernel.Bind<IUserService>().To<UserService>(); 
     kernel.Bind<ICampusService>().To<CampusService>(); 
     kernel.Bind<InventoryUOW>().To<EF_UOW>().DefinesNamedScope(scopeName); 
     kernel.Bind<IInventoryUowFactory>().ToFactory(); 
     kernel.Bind<IRepositoryFactory>().ToFactory().InNamedScope(scopeName); 
     kernel.Bind<DbContext>().To<InventoryContext>(); 
     kernel.Bind<InventoryContext>().ToSelf().InNamedScope(scopeName); 
     kernel.Bind<IUserRepository>().To<EF_UserRepository>(); 
     kernel.Bind<ExtendedMembershipProvider>().ToMethod(x => (SimpleMembershipProvider)Membership.Provider); 

     kernel.Bind<IPrincipal>().ToMethod(x => HttpContext.Current.User); 


     kernel.Bind<IWebSecurityWrapper>().To<WebSecurityWrapper>(); 
     kernel.Bind<IRepository<Campus>>().To<Repository<Campus>>(); 
: 보테 public EF_UOW(IRepositoryFactory factory, InventoryContext context) 하고 여기에 public Repository(DbContext context)

바인딩에 그 일의 시도이다

이 (UserRepository에 의해 구현) 사용자 정의 저장소 인터페이스 IUserRepository

어떤 아이디어를 사용하는 경우 어떤 이유로 작동하는 반면 나는 IRepository<Campus> 같은 일반적인 저장소 인터페이스를 사용하고있는 경우 실패 바인딩 ?? 감사합니다.

+0

는 바인딩'IRepository 는'실패 방법에 대해 자세히 설명하십시오. 또한 왜'IRepository' 인터페이스 p.Ex에 제네릭 메소드 대신 일반'IRepository '인터페이스가 필요한지 궁금합니다. 'IRepository.Load (id)'. EF 디자인 때문입니까? 그렇다면이 디자인을 묘사 한 EF 문서 링크를 제공하기에 충분히 친절하십니까? – BatteryBackupUnit

답변

0

질문에 잘 부탁드립니다. 감사합니다.

우리의 응용 프로그램에서 우리는 같은 문제를 해결해야했습니다. 이 답변이 도움이된다면보기 : 그것은하지만, 명명 된 범위를 사용하지 않는 것

How to use Ninject in a multi-threaded Windows service to get new instances of a dependency (DbContext) on every tick?

. 위의 대답은 내가 그것을 개선하기 위해 행복 해요만큼 상세하지 않으면 그것은의 UnitOfWork이 완료 될 때마다 다시 얻을 스레드 지역 주민들을 사용

(= 배치).

관련 문제