2012-09-12 4 views
11

J'utilise le motif Unité de travail et Référentiel générique dans mon application MVC 4. Le problème que j'essaie de résoudre consiste à créer des stubs de référentiel pour chaque entité de mon système. Pour utiliser Autofac Ioc, je dois créer une classe et une interface de référentiel pour chaque entité afin de pouvoir l'enregistrer dans Autofac.MVC 4 Autofac et le modèle de référentiel générique

début app ...

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

classe Repository

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

Interface

public interface ISchoolDetailRepository : IRepository<SchoolDetail> 
{ 
} 

Il semble que beaucoup de travail supplémentaire.

Existe-t-il un moyen d'enregistrer le référentiel générique de Type plutôt que de créer toutes ces classes vides?

Puis dans ma classe de service que je peux juste avoir le type générique passé dans le constructeur via Ioc comme ...

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; 
    } 
} 

config Container

// 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)); 

l'exception provient du code ci-dessus où l'expression que vous me donniez Runs ..

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 

}

Répondre

28

Vous avez besoin de la fonction open generics de Autofac:

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

Ensuite, vous utilisez vos référentiels exactement comme vous l'avez:

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

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

Que dois-je faire pour mes entités pour faire ce travail? J'utilise Code First pour que mes Entités ne soient que des POCO simples. J'obtiens une erreur .. Entities.SchoolDetail n'est pas une définition de type générique ouverte. – JBeckton

+0

Vous n'avez pas besoin d'entrer avec vos Entités. Si vous avez un 'RepositoryBase : IRepository ' alors vous ajoutez simplement cette ligne à votre constructeur de conteneur 'builder.RegisterGeneric (typeof (RepositoryBase <>)) .As (typeof (IRepository <>));' et cela devrait fonctionner. Vous n'avez pas besoin de le faire pour chaque entité. Pouvez-vous poster un peu plus de code à quoi ressemble la configuration actuelle du conteneur et d'où obtenez-vous l'exception? – nemesv

+0

voir la mise à jour .. l'erreur se produit dans le App_Start sur la ligne qui utilise le RegisterGeneric – JBeckton

Questions connexes