У меня есть требование, когда мне нужно вставить несколько DBContext (Entity Framework) в конструктор. Один DBContext доступен только для чтения, а другой - для чтения и записи, указывая на разные БД. Мой код структурирован, как показано ниже.
У меня есть два репозитория как 1. IReportRepository 2. ISystemRepository Ниже приведена структура репозитория
public interface ISystemRepository
{
IRepository<AuditLog> AuditLogs { get; }
IRepository<Group> Groups { get; }
IRepository<Enterprise> Enterprises { get; }
}
У меня есть конкретная реализация для выше
public class SystemRepository : ISystemRepository
{
[Inject]
public IRepository<AuditLog> AuditLogs { get; set; }
[Inject]
public IRepository<Group> Groups { get; set; }
[Inject]
public IRepository<Enterprise> Enterprises { get; set; }
}
Аналогично у меня есть реализация для IReportRepository
Каждый из них - это зависимость, внедряемая с использованием Ninject
Bind<IRepository<AuditLog>>().To<EFRepository<AuditLog>>();
Bind<IRepository<Group>>().To<EFRepository<Group>>();
Bind<IRepository<Enterprise>>().To<EFRepository<Enterprise>>();
EFRepository -
public class EFRepository<T> : IRepository<T> where T : class, IEntity
{
protected readonly IDbContext Context;
protected readonly IDbSet<T> Entities;
public EFRepository(IDbContext context)
{
Context = context;
Entities = context.Set<T>();
}
}
Мне нужно пройти И ISytemRepository, и IReportRepository для конструктора классов, как показано ниже, для каждого из них требуется различный DBContext для разных БД.
public ReportingController(ISystemRepository repository,[Named("Report")][ReportContext] IReportRepository reportRepository)
Атрибут ReportContext приведен ниже.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
AllowMultiple = true, Inherited = true)]
public class ReportContextAttribute : ConstraintAttribute
{
public override bool Matches(IBindingMetadata metadata)
{
return metadata.Has("IsReport") && metadata.Get<bool>("IsReport");
}
}
Введено как
Bind<IDbContext>().To<ReportContext>().WhenAnyAncestorNamed("Report").WithMetadata("IsReport", true);
Bind<IDbContext>().To<PracticeContext>().WhenNoAncestorNamed("Report").InRequestScope();
Bind<ISystemRepository>().To<SystemRepository>();
Bind<IReportRepository>().To<ReportRepository>().Named("Report");
Я также пытался добавить атрибуты ReportRepo к членам IReportRepository
[ReportRepo]
public class ReportRepository : IReportRepository
{
[Inject, ReportRepo]
public IRepository<AuditLog> AuditLogs { get; set; }
[Inject, ReportRepo]
public IRepository<Group> Groups { get; set; }
[Inject, ReportRepo]
public IRepository<Enterprise> Enterprises { get; set; }
[Inject, ReportRepo]
public IRepository<EnterpriseSetting> EnterpriseSettings { get; set; }
}
Bind<IDbContext>().To<ReportContext>().WhenTargetHas<ReportRepoAttribute>();
Bind<IDbContext>().To<ReportContext>().WhenClassHas<ReportRepoAttribute>();
Bind<IDbContext>().To<ReportContext>().WhenMemberHas<ReportRepoAttribute>();
Но, похоже, ничего не работает, он принимает либо DBContext, и внедряет в оба репозитория.
Примечание. Мне известно о введении свойства как о запахе кода, и я буду проводить рефакторинг.
Заранее благодарим за любая помощь.