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

如果你有一个循环依赖,它是你应该修改你的架构的线索。

如果您需要“让数据项目引用合同项目”,那么合同不能引用数据来获取实体。你说“业务和数据需要看到实体类”,那么为什么不把你的实体作者保留在实体项目中。

数据 - >引用合同 - >引用实体 合同 - >引用实体

或者作为替代,在合同项目,而不是数据定义你的实体。