Нужно несколько DBContext введены в один класс - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть требование, когда мне нужно вставить несколько 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, и внедряет в оба репозитория.

Примечание. Мне известно о введении свойства как о запахе кода, и я буду проводить рефакторинг.

Заранее благодарим за любая помощь.

...