2012-09-12 24 views
11

Estoy utilizando el patrón Unidad de trabajo y Repositorio genérico en mi aplicación MVC 4. El problema que estoy tratando de resolver es crear resguardos de depósito para cada entidad en mi sistema. Para utilizar Autofac Ioc, tengo que crear una clase e interfaz de repositorio para cada entidad, de modo que pueda registrarlo en Autofac.MVC 4 Autofac y el modelo de Repositorio genérico

inicio de aplicaciones ...

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

clase Repositorio

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

interfaz

public interface ISchoolDetailRepository : IRepository<SchoolDetail> 
{ 
} 

Parece que una gran cantidad de trabajo extra.

¿Hay alguna forma de registrar el repositorio genérico Tipo en lugar de crear todas estas clases vacías?

Luego, en mi clase de servicio que sólo puede tener el tipo genérico pasado al constructor a través de Ioc como ...

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

Container config

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

la excepción proviene de que el código anterior donde la expresión que me diste se ejecuta ...

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 

}

Respuesta

28

Usted necesita la función open generics de Autofac:

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

continuación, utiliza los repositorios exactamente como usted la describe:

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

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

¿Qué tengo que hacer para mis Entidades para hacer que esto funcione? Estoy usando Code First para que mis entidades sean simplemente POCO. Me sale un error .. Entities.SchoolDetail no es una definición de tipo genérico abierto. – JBeckton

+0

No necesita tener sus Entites. Si tiene un 'RepositoryBase : IRepository ', simplemente agregue esta línea a su containerbuilder 'builder.RegisterGeneric (typeof (RepositoryBase <>)) .As (typeof (IRepository <>));' y debería funcionar. No es necesario que lo haga por cada entidad. ¿Puedes publicar un código más de cómo se ve la configuración del contenedor real y de dónde obtienes la excepción? – nemesv

+0

ver actualización ... el error ocurre dentro de App_Start en la línea que usa el RegisterGeneric – JBeckton

Cuestiones relacionadas