循环组件依赖性检测到具有 autofac 依赖性注入的存储库模式

Circular component dependency detected Repository pattern with autofac dependency injections

我正在使用 db Context 和 Autofac DI 实现通用存储库模式,我正在使用基于依赖注入的构造函数。

我创建了三层存储库模式,它们是:

现在,当我尝试在 ContactController 和 运行 应用程序中传递 IContactService 接口时,我正在 MVC Web 应用程序中使用此架构。

我收到循环依赖检测错误。以下是我的项目代码。

存储库代码:

public class Repository<T> : IRepository<T> where T : class
{
    private InvoiceBillingDbContext db;
    private DbSet<T> dbSet;

    public Repository()
    {
        db = new InvoiceBillingDbContext();
        dbSet = db.Set<T>();
    }
    public IEnumerable<T> GetAll()
    {
        return dbSet.ToList();
    }

    public T GetById(object Id)
    {
        return dbSet.Find(Id);
    }

    public void Insert(T obj)
    {
        dbSet.Add(obj);
        Save();
    }
    public void Update(T obj)
    {
        db.Entry(obj).State = EntityState.Modified;
        Save();
    }
    public void Delete(object Id)
    {
        T getObjById = dbSet.Find(Id);
        dbSet.Remove(getObjById);
    }
    public void Save()
    {
        db.SaveChanges();
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (this.db != null)
            {
                this.db.Dispose();
                this.db = null;
            }
        }
    }

    public void AddRange(List<T> obj)
    {
        dbSet.AddRange(obj);
        Save();
    }

    public IEnumerable<T> Get(Expression<Func<T, bool>> predicate)
    {
        return dbSet.Where(predicate);
    }
}

接口 IRepository

public interface IRepository<T> where T : class
{
        IEnumerable<T> GetAll();
        T GetById(object Id);
        IEnumerable<T> Get(Expression<Func<T, bool>> predicate);
        void Insert(T obj);
        void AddRange(List<T> obj);
        void Update(T obj);
        void Delete(Object Id);
        void Save();
}

我的联系人资料库

public class ContactRepository:Repository<Contact>, IContactRepository
{
        private IContactRepository _contractRepo;
        public ContactRepository(IContactRepository contractRepo)
        {
            this._contractRepo = contractRepo;
        }
}

我的 ContactRepository 界面

public interface IContactRepository:IRepository<Contact>
{
}

我的联系服务

public interface IContactService
{
        void AddContact(Contact contact);
        IEnumerable<Contact> GetContactsByTypeId(int typeId);
}

public class ContactService : IContactService
{
        private readonly IContactRepository _contactRepository;
        public ContactService(IContactRepository contactRepository)
        {
            this._contactRepository = contactRepository;
        }
        public void AddContact(Contact contact)
        {
            _contactRepository.Insert(contact);
        }

        public IEnumerable<Contact> GetContactsByTypeId(int typeId)
        {
            return _contactRepository.Get(i => i.TypeID == typeId);
        }
}

我的控制器

public class ContactController : Controller
{
        // GET: Contact
        private IContactService _contactService;

        public ContactController(IContactService contactService)
        {
            this._contactService = contactService;
        }
        public ActionResult Index()
        {
            return View(new ContactViewModel());
        }

        public ActionResult AddContact(ContactViewModel contact)
        {
            if (ModelState.IsValid)
            {
                var _contactMapper = Mapper.Map<ContactViewModel, Contact>(contact);
                _contactService.AddContact(_contactMapper);
                ViewBag.Message = "Successfully Saved";
                return View("Index",new ContactViewModel());
            }
            ViewBag.Message = "Error Occur Please try Again!";
            return View("Index", new ContactViewModel());
        }
}

和 Autofac 依赖注入

public static void ConfigureContainer()
{
            var builder = new ContainerBuilder();

            // Register all controllers in the Mvc Application assembly
            builder.RegisterControllers(typeof(MvcApplication).Assembly);

            // Registered Warehouse Reservoir Service
            builder.RegisterType<InvoiceRepository>().As<IInvoiceRepository>();
            // Registration Service Layer Service
            builder.RegisterType<InvoiceService>().As<IInvoiceService>();
            builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
            // Registered Warehouse Reservoir Service
            builder.RegisterType<JournalVoucherRepository>().As<IJournalVoucherRepository>();
            // Registration Service Layer Service
            builder.RegisterType<JournalVoucherService>().As<IJournalVoucherService>();



            // Registered Warehouse Reservoir Service
            builder.RegisterType<ContactRepository>().As<IContactRepository>();
            // Registration Service Layer Service
            builder.RegisterType<ContactService>().As<IContactService>();




            // Registration filter
            builder.RegisterFilterProvider();

            var container = builder.Build();

            // Setting Dependency Injection Parser
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

您只有一个 IContactRepository 的实现。你还有一个通用的 IRepository<T>.

您的 IContactRepository 实现被注入了另一个 IContactRepository。因此,您正在递归解析相同的 class 并将其注入自身。

public class ContactRepository:Repository<Contact>, IContactRepository
{
        private IContactRepository _contractRepo;

        // In order to resolve IContractRepository, the container has to 
        // resolve another IContractRepository to inject into it. 
        // And another one to inject into that. It's recursive.
        public ContactRepository(IContactRepository contractRepo)
        {
            this._contractRepo = contractRepo;
        }
}

您的示例没有显示 ContactRepository 如何使用注入其中的 IContactRepository。但是这个

public interface IContactRepository:IRepository<Contact>
{
}

表明它使用的方法与 IRepository<Contact> 中的方法完全相同,因为 IContactRepository 除了那些方法之外没有任何其他方法。

所以你很可能只需要修改 ContactRepository 来注入 IRepository<Contact>,而不是 IContactRepository

public class ContactRepository:Repository<Contact>, IContactRepository
{
        private IRepository<Contact> _contractRepo;

        public ContactRepository(IRepository<Contact> contractRepo)
        {
            this._contractRepo = contractRepo;
        }
}

这很容易被忽视,因为两个接口具有完全相同的方法。