2016-09-04 4 views
2

내가 작업중인 프로젝트에서 일부 레이어를 분리하려고합니다. 아이디어는 웹 사이트에있는 모든 기능을 사용하고 모듈화 할 수 있다는 것입니다. 예를 들어, 뉴스와 같은 것을 가져 와서 웹 사이트에 기능을 추가하려면 코드에서 뉴스 서비스와 모델, 데이터 레이어 등을 가져와야합니다. 모든 코드가 가져 오기됩니다.다른 프로젝트에서 DbContext 확장

프로젝트의 일부로 Ninject를 사용하여 종속성을 주입하므로 구체적인 클래스를 참조 할 필요가 없으며 계약 만 참조한다는 점에 유의하십시오.

나는 같은 내 주요 프로젝트 및 데이터 레이어를 가지고 :

public class MainDbContext : CustomIdentityDbContext, IMainDbContext 
{ 

} 

당신이이 같이 보이는 CustomIdentityDbContext를 확장 볼 수 있듯이 :

public class CustomIdentityDbContext : IdentityDbContext<CustomUser>, ICustomIdentityDbContext 
{ 
    public CustomIdentityDbContext() 
     : base("DefaultConnection", throwIfV1Schema: false) 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim"); 
     modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole"); 
     modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin"); 
     modelBuilder.Entity<IdentityRole>().ToTable("Role"); 
     modelBuilder.Entity<AzularisUser>().ToTable("User"); 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
    } 

    public static DbContext Create() 
    { 
     return new CustomIdentityDbContext(); 
    } 
} 

내 문제는 내가 가질 필요가 있다는 것입니다 뉴스 테이블을 만든 다음 ID와 마찬가지로 해당 테이블을 매핑하는 데 EF6이 필요합니다. 내가 알 수없는 것은이 관계를 만드는 방법입니다. 어떻게 거기에 그 라인을 작성하고 News 객체를 참조 할 필요없이 DbSet<News> News { get; set; }을 내 MainDbContext에 추가 할 수 있습니까? 그래서 나는 그 서비스가 ninject와 바인딩을 통해 스스로를 생성하기 위해 모든 다른 클래스를 트리거 할 것이므로 내 서비스를 참조 할 때 동적으로 MainDbContext 클래스에 추가되도록하려고합니다.

즉, 뉴스 용 데이터 레이어는 MainDbContext를 참조하지 않고 MainDbContext에 자신을 삽입해야합니다. 이게 가능한가? 그렇다면 어떻게 달성 할 수 있을까요?

public class NewsDbContext : DbContext, INewsDbContext 
{ 
    public DbSet<News> News { get; set; } 
    public NewsDbContext() : base("DefaultConnection") { } 

    public IEnumerable<INews> QueryNews() 
    { 
     return News; 
    } 
} 

위의 코드는 컴파일 및 실행은, 그러나, 그것은 테이블을 생성하지 않으며, 나는 그것을 쿼리하거나 레코드를 삽입 할 때, 그것은 테이블로 중단됩니다 여기

내가 뭘하려 존재하지 않습니다. 나는 이것을 어떻게 성취 할 수 있을지 잘 모르겠다. 나는 생각을 많이 잃는다. 이게 가능한가?

편집 : 내가 없을 수 있습니다 실현 제대로 자신을 설명

. 내가 다시 시도하자. 나는 다층 구조를 가지고있다. 서비스, ​​데이터, 도메인 및 DTO 레이어가 있습니다. 이 4 개의 레이어는 플러그인을 구성합니다. 이 4 개의 레이어 위에는이 레이어의 인터페이스가 4 개 더 있으며, 다시 말하면 계약입니다. Ninject를 사용하여 계약을 구현 레이어에 바인딩하여 주 프로젝트가 실제로 프로젝트의 구현 레이어를 참조하지 않도록합니다. 이런 이유로 저는 메인 프로젝트 데이터 레이어에 실제로 플러그인의 데이터 레이어를 참조하지 않고 데이터 레이어를 메인 프로젝트의 데이터 레이어에 연결하려고 시도하고 있습니다. 문제는 플러그인에 자체적으로 필요한 테이블이 있다는 것입니다. 프로젝트를 처음 실행하면 EF6을 사용하여이 테이블을 자동으로 생성하고 싶습니다.

내 메인 프로젝트도 플러그인과 같은 방식으로 분할되어 있으며 4 개의 레이어와 관리자 레이어가 모두 있습니다. 관리자는 서비스 콜렉션이며 다른 용도로는 사용되지 않습니다. 단지 Ninject의 도움을 받아 계약을 기반으로 인스턴스를 생성합니다. 프로젝트의 핵심은 모든보기, 스크립트 및 CSS 파일을 보유하지만 관리자 인터페이스를 참조합니다. ninject를 사용하여 관리자 인스턴스를 만듭니다. 관리자는 다시 계약에 대한 모든 참조를 가지며, 계약을 통해 해당 계약의 인스턴스를 만듭니다. 서비스는 데이터 계층의 계약을 참조하고 데이터 계층은 정보를 쿼리하고 결과를 다시 컨트롤러로 전달 될 서비스로 가져옵니다. 내 구조가 좀 더 나아 졌으면 좋겠다.이 접근 방식을 사용하면 dll 구현을 바꿀 수 있고 프로젝트가 계속 작동 할 수있는 trully 모듈 프로젝트를 만들려고 시도하고 있습니다. 전체 프로젝트를 다시 컴파일 할 필요가 없습니다. 나는 2 개의 DLL에 2 개의 완전히 분리 된 기능을 가질 수 있지만 동일한 계약을 구현하는 한 웹 사이트는 해당 폴더에있는 DLL과 상관없이 작동해야합니다.

방금 ​​설명한 모든 작업이 EF6에서 작동하는 것을 제외하고는 모두 작동합니다. 나는 DAPPER가있는 장소에서 매우 비슷한 구조를 가지고 있으며, 당신이 당신 자신의 질의 등을 작성했을 때 그 모든 멋진 멋쟁이가있어서 아무런 문제가 없었습니다. 나는 이것을 EF6으로 복제하려하고있다. 그래서 다시, 내 질문에, 어떻게 테이블을 만들 EF6, 동적으로 추가 할 수있는 유일한 참조 할 때 서비스 인터페이스를 추가 할 수 있습니다. 어쩌면 인터페이스에 MapTables 함수가있을 수 있지만 다시 EF6에 동적 추가를 수행하는 방법을 모르겠습니다.

내가 가지고있는 생각이 작동 할 수 있는지, 어떻게 할 수 있을지 확실하지 않지만 DB 컨텍스트를 확장하는 대신 형식으로 전달하면 어떻게 될까요?

+0

일반적으로 'NewsDbContext'는 'CustomIdentityDbContext'의 하위 클래스 여야합니다. 그러나 올바르게 이해한다면,'News'를 포함하는 어셈블리를 "기본"어셈블리와 독립적으로 만들고 싶습니다. 즉, 웹 응용 프로그램은 기본 어셈블리와 다른 어셈블리를 가져올 수 있어야하며 어떻게 든 하나의 데이터 계층으로 병합해야합니다. 그 맞습니까? –

+0

@GertArnold 예 하나의 데이터 레이어로 병합하기를 바라고 있습니다. 웹 애플리케이션은 뉴스 어셈블리를 가져 와서 서비스를 통해 사용할 수 있어야합니다. – Bojan

+0

큰 질문은 다음과 같습니다. * who * (어느 어셈블리)가 어떤 클래스가 Entity Framework 클래스 모델의 일부인지 알고 있습니까? –

답변

1

일부 문제가 해결되었습니다. 나는 이것을 풀 버전으로 풀어서 대답과 업데이트로 게시 할 것입니다. 지금까지 나는 테이블을 생성하는 방법을 배웠습니다. 그것은 주요 프로젝트의 DB 컨텍스트 내에서 다음 코드입니다 :

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    var entityMethod = typeof(DbModelBuilder).GetMethod("Entity"); 

    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
    { 
     var entityTypes = assembly 
      .GetTypes() 
      .Where(t => 
      t.GetCustomAttributes(typeof(PersistentAttribute), inherit: true) 
      .Any()); 

     foreach (var type in entityTypes) 
     { 
      entityMethod.MakeGenericMethod(type) 
       .Invoke(modelBuilder, new object[] { }); 
     } 
    } 

    base.OnModelCreating(modelBuilder); 
} 

위의 코드는 테이블이있는 모든 클래스에 대해 생성되는 것을 보장한다 "PersistentAttribute '이 (가) 추가되었습니다. 내 다음 문제는 외부 DLL에서 쿼리하려고합니다. 따라서 뉴스 프로젝트의 데이터 레이어는 주 프로젝트에서 생성 된 컨텍스트를 어떻게 든 통과하게함으로써 자체적으로 쿼리 할 수 ​​있어야합니다. 나는 그 아이디어에 대해 감사 드리지 않고, 알아 낸 후에 더 게시 할 것입니다.