[英]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
注入其中。 所以你遞歸地解析同一個類並將它注入到自身中。
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;
}
}
這很容易被忽視,因為兩個接口都有完全相同的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.