2012-09-12 20 views
11

私はMVC 4アプリケーションでユニット・オブ・ワークと汎用リポジトリ・パターンを利用しています。私が解決しようとしている問題は、システム内のすべてのエンティティのリポジトリ・スタブを作成することです。 Autofac Iocを利用するためには、すべてのエンティティのためのリポジトリクラスとインターフェイスを作成して、Autofacに登録できるようにしなければなりません。MVC 4 Autofacと汎用リポジトリのパターン

アプリ開始...

builder.RegisterType<SchoolDetailRepository>().As<ISchoolDetailRepository>().InstancePerHttpRequest(); 

リポジトリクラス

public class SchoolDetailRepository : RepositoryBase<SchoolDetail>, ISchoolDetailRepository 
{ 
    public SchoolDetailRepository(IDatabaseFactory databaseFactory) : base(databaseFactory) 
    { 
    } 
} 

インタフェース

public interface ISchoolDetailRepository : IRepository<SchoolDetail> 
{ 
} 

それは余分な作業の多くのように思えます。

これらの空のクラスをすべて作成するのではなく、汎用リポジトリを登録する方法はありますか?

はその後、私のサービスクラスに私はジェネリック型のようなIocを介して、コンストラクタに渡されることができます...

public class SchoolService : ISchoolService 
{ 
    private readonly IRepository<SchoolDetail> _schoolRepository; 
    private readonly IUnitOfWork _unitOfWork; 

    public SchoolService(IRepository<SchoolDetail> schoolRepository, IUnitOfWork unitOfWork) 
    { 
     this._schoolRepository = schoolRepository; 
     this._unitOfWork = unitOfWork; 
    } 
} 

コンテナ設定

// Autofac iOC 
     var builder = new ContainerBuilder(); 
     // register controllers 
     builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

     // register services 
     builder.RegisterType<MembershipService>().As<IMembershipService>().InstancePerHttpRequest(); 
     builder.RegisterType<SchoolService>().As<ISchoolService>().InstancePerHttpRequest(); 
     builder.RegisterType<StudentService>().As<IStudentService>().InstancePerHttpRequest(); 
     builder.RegisterType<ClassRoomService>().As<IClassRoomService>().InstancePerHttpRequest(); 
     builder.RegisterType<CourseService>().As<ICourseService>().InstancePerHttpRequest(); 
     builder.RegisterType<SchoolYearService>().As<ISchoolYearService>().InstancePerHttpRequest(); 
     builder.RegisterType<EnrollmentService>().As<IEnrollmentService>().InstancePerHttpRequest(); 
     builder.RegisterType<TeacherService>().As<ITeacherService>().InstancePerHttpRequest(); 

     // register data infrastructure 
     builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest(); 
     builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest(); 

     // register repositories 
     builder.RegisterType<SchoolRepository>().As<ISchoolRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<TeacherRepository>().As<ITeacherRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<MembershipRepository>().As<IMembershipRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<RoleRepository>().As<IRoleRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<ProfileRepository>().As<IProfileRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<StudentRepository>().As<IStudentRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<ClassRoomRepository>().As<IClassRoomRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<CourseRepository>().As<ICourseRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<EnrollmentRepository>().As<IEnrollmentRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<SchoolYearRepository>().As<ISchoolYearRepository>().InstancePerHttpRequest(); 
     builder.RegisterType<GradeLevelRepository>().As<IGradeLevelRepository>().InstancePerHttpRequest(); 
     //builder.RegisterType<SchoolDetailRepository>().As<ISchoolDetailRepository>().InstancePerHttpRequest(); 
     builder.RegisterGeneric(typeof(RepositoryBase<SchoolDetail>)).As(typeof(IRepository<SchoolDetail>)); 

     // build and setup resolver 
     IContainer container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

例外は、上記のコードから来ていますあなたが私に与えた表情はどこで実行されますか。

builder.RegisterGeneric(typeof(RepositoryBase<SchoolDetail>)).As(typeof(IRepository<SchoolDetail>)); 

RepositoryBase

public abstract class RepositoryBase<T> where T : class 
{ 
private LearningCompactPilotContext _dataContext; 
private readonly IDbSet<T> _dbset; 
protected RepositoryBase(IDatabaseFactory databaseFactory) 
{ 
    DatabaseFactory = databaseFactory; 
    _dbset = DataContext.Set<T>(); 
} 

protected IDatabaseFactory DatabaseFactory 
{ 
    get; private set; 
} 

protected LearningCompactPilotContext DataContext 
{ 
    get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); } 
} 

... more code 

}

答えて

28

あなたはAutofacのopen generics機能が必要です。そして、あなたが説明したとおりに、あなたのリポジトリを使用し

builder.RegisterGeneric(typeof(RepositoryBase<>)) 
    .As(typeof(IRepository<>)); 

を:

public class SomeService 
{ 
    private readonly IRepository<SomeEntity> _repository; 

    public SchoolService(IRepository<SomeEntity> repository) 
    { 
     this._repository= repository; 
    } 
} 
+0

私が行うには何を持っていますこの仕事をするために私の団体は?私はCode Firstを使用しているので、エンティティは単なるPOCOです。エラーが表示されます。Entities.SchoolDetailは開いたジェネリック型定義ではありません。 – JBeckton

+0

あなたはあなたのエンゲージでエンゲージする必要はありません。 'RepositoryBase :IRepository 'をお持ちの場合は、この行をコンテナビルダー 'builder.RegisterGeneric(typeof(RepositoryBase <>)).As(typeof(IRepository <>));'に追加するだけで動作します。あなたはすべてのエンティティのためにそれを行う必要はありません。実際のコンテナの設定がどのようになっているのか、どこから例外が得られるのか、さらにコードを投稿できますか? – nemesv

+0

updateを参照してください。RegisterGenericを使用する行のApp_Start内でエラーが発生します。 – JBeckton

関連する問題