0

我有這種情況:Circular Reference + IoC

Web項目 - 使用Unity 3調用業務類IoC。 Web項目沒有看到業務項目。它只是引用合同項目。

namespace Biblioteca.Web.Controllers 
{ 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      return View(); 

      var Autor = Inject.Resolve<IAutorBO>(); 
     } 
    } 
} 

業務項目 - 這裏我使用Unity 3 IoC指向數據項目中的AutorDO類(見下文)。業務項目沒有看到數據項目。

namespace Biblioteca.Data 
{ 
    public sealed partial class AutorBO : IAutorBO 
    {     
     #region Atributos 

     private IAutorDO AutorDO = Inject.Resolve<IAutorDO>(); 

     #endregion 

     #region Métodos Interface 

     public IQueryable<DTOAutor> GetAll() 
     { 
      return AutorDO.GetAll(); 
     } 

     public DTOAutor GetById(int id) 
     { 
      return AutorDO.GetById(id); 
     } 

     void IAutorBO.Insert(DTOAutor dto) 
     { 
      AutorDO.Insert(dto); 
     } 

     void IAutorBO.Delete(DTOAutor dto) 
     { 
      AutorDO.Delete(dto); 
     } 

     void IAutorBO.Update(DTOAutor dto) 
     { 
      AutorDO.Update(dto); 
     } 

     //IQueryable<DTOAutor> IAutorBO.SearchFor(Expression<Func<Autor, bool>> predicate) 
     //{ 
     // return AutorDO.SearchFor(predicate); 
     //} 

     IQueryable<DTOAutor> IAutorBO.GetAll() 
     { 
      return AutorDO.GetAll(); 
     } 

     DTOAutor IAutorBO.GetById(int id) 
     { 
      return AutorDO.GetById(id); 
     } 

     #endregion 

     #region Outros Métodos 

     #endregion 
    } 
} 

數據訪問項目 - 這是我的數據項目。

namespace Biblioteca.Data 
{ 
    public sealed partial class AutorDO : IAutorDO 
    { 
     #region Atributos 

     Repository<Autor> repository = new Repository<Autor>(); 

     #endregion 

     #region Implementações Interface 

     /// <summary> 
     /// Implementação do método de interface Insert 
     /// </summary> 
     /// <param name="dto"></param> 
     void IAutorDO.Insert(Transport.DTOAutor dto) 
     { 
      Autor entity = AssemblerAutor.ToEntity(dto); 
      repository.Insert(entity); 
     } 

     /// <summary> 
     /// Implementação do método de interface Delete 
     /// </summary> 
     /// <param name="dto"></param> 
     void IAutorDO.Delete(Transport.DTOAutor dto) 
     { 
      Autor entity = AssemblerAutor.ToEntity(dto); 
      repository.Delete(entity); 
     } 

     /// <summary> 
     /// Implementação do método de interface Update 
     /// </summary> 
     /// <param name="dto"></param> 
     void IAutorDO.Update(Transport.DTOAutor dto) 
     { 
      Autor entity = AssemblerAutor.ToEntity(dto); 
      repository.Update(entity); 
     } 

     /// <summary> 
     /// Implementação do método de interface SearchFor 
     /// </summary> 
     /// <param name="dto"></param> 
     /// <returns></returns> 
     //IQueryable<Transport.DTOAutor> IAutorDO.SearchFor(Expression<Func<Autor, bool>> predicate) 
     //{ 
     // IQueryable<Autor> list = repository.SearchFor(predicate); 
     // IQueryable<Transport.DTOAutor> dtoList = (IQueryable<Transport.DTOAutor>)AssemblerAutor.ToDTOs(list); 
     // return dtoList; 
     //} 

     /// <summary> 
     /// Implementação do método de interface GetAll 
     /// </summary> 
     /// <returns></returns> 
     IQueryable<Transport.DTOAutor> IAutorDO.GetAll() 
     { 
      IQueryable<Autor> list = repository.GetAll(); 
      IQueryable<Transport.DTOAutor> dtoList = (IQueryable<Transport.DTOAutor>)AssemblerAutor.ToDTOs(list); 
      return dtoList; 
     } 

     /// <summary> 
     /// Implementação do método de interface GetById 
     /// </summary> 
     /// <param name="id"></param> 
     /// <returns></returns> 
     Transport.DTOAutor IAutorDO.GetById(int id) 
     { 
      Autor entity = new Autor(); 
      Transport.DTOAutor dto = new Transport.DTOAutor(); 

      using (var ctx = new BibliotecaContext()) 
      { 
       entity = repository.GetById(id); 
       dto = AssemblerAutor.ToDTO(entity); 
      } 

      return dto; 
     } 

     #endregion 
    } 
} 

業務和數據項目都引用具有所有Unity 3 IoC接口的合同項目,用於實現IoC。下面是用來實現的IoC接口:

namespace Biblioteca.Contracts 
{ 
    public interface IAutorBO 
    { 
     #region Métodos CRUD 

     void Insert(DTOAutor dto); 
     void Delete(DTOAutor dto); 
     void Update(DTOAutor dto); 
     //IQueryable<DTOAutor> SearchFor(Expression<Func<Autor, bool>> predicate); 
     IQueryable<DTOAutor> GetAll(); 
     DTOAutor GetById(int id); 

     #endregion 
    } 
} 

namespace Biblioteca.Contracts 
{ 
    public interface IAutorDO 
    { 
     #region Métodos CRUD 

     void Insert(DTOAutor dto); 
     void Delete(DTOAutor dto); 
     void Update(DTOAutor dto); 
     //IQueryable<DTOAutor> SearchFor(Expression<Func<Autor, bool>> predicate); 
     IQueryable<DTOAutor> GetAll(); 
     DTOAutor GetById(int id); 

     #endregion 
    } 
} 

爲補充,我用一個通用的存儲庫,如下圖所示:

namespace Biblioteca.Data 
{ 
    /// <summary> 
    /// Interface para classe genérica para métodos CRUD 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public interface IRepository<T> 
    { 
     void Insert(T entity); 
     void Delete(T entity); 
     void Update(T entity); 
     IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate); 
     IQueryable<T> GetAll(); 
     T GetById(int id); 
    } 
} 

namespace Biblioteca.Data 
{ 
    /// <summary> 
    /// Classe genérica para métodos CRUD da camada Data 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class Repository<T> : IRepository<T> where T : class 
    { 
     #region Attributes 

     protected DbSet<T> dbset; 
     protected DbContext ctx; 

     #endregion 

     #region Constructor 

     public Repository() 
     { } 

     public Repository(DbContext ctx) 
     { 
      this.ctx = ctx; 
      dbset = ctx.Set<T>(); 
     } 

     #endregion 

     #region IRepository<T> Members 

     public void Insert(T entity) 
     { 
      if (dbset.Contains(entity)) 
      { 
       Update(entity); 
      } 
      else 
      { 
       dbset.Add(entity); 
      } 
     } 

     public void Delete(T entity) 
     { 
      dbset.Remove(entity); 
     } 

     public void Update(T entity) 
     { 
      using (ctx) 
      { 
       ctx.Set<T>().Attach(entity); 
       ctx.SaveChanges(); 
      } 
     } 

     public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate) 
     { 
      return dbset.Where(predicate); 
     } 

     public IQueryable<T> GetAll() 
     { 
      return dbset; 
     } 

     public T GetById(int id) 
     { 
      return dbset.Find(id); 
     } 

     #endregion 
    } 
} 

請注意,我在所有的一類方法評價。此方法無法實現,因爲它會導致循環依賴。

我有數據項目引用合同項目。但是我不能使用「SearchFor」方法,因爲它需要Data Project中的Entity Autor。

請注意,Business和Data都需要查看實體類,因爲我有相同的方法簽名。

我需要一些方法來允許使用的IoC是的方式,其中網未引用企業和企業不引用的數據,並能創建其他的方法,我可以通過實體參數。

有什麼建議嗎?我已經嘗試創建第三個項目並指向它,但我無法使其工作。有沒有可能使用反射?如果可能的話,如何?

我會很感激任何建議。

+0

任何人都知道如何解決?這是非常重要的,因爲我有一個架構來完成。謝謝。 – Olivertech

回答

0

如果你有一個循環依賴,它是你應該修改你的架構的線索。

如果您需要「讓數據項目引用合同項目」,那麼合同不能引用數據來獲取實體。你說「業務和數據需要看到實體類」,那麼爲什麼不把你的實體作者保留在實體項目中。

數據 - >引用合同 - >引用實體 合同 - >引用實體

或者作爲替代,在合同項目,而不是數據定義你的實體。