이 상황이 있습니다 :순환 참조 + IoC
웹 프로젝트 - Unity 3 IoC를 사용하여 비즈니스 클래스를 호출하는 중입니다. 웹 프로젝트에는 비즈니스 프로젝트가 표시되지 않습니다. 단지 Contracts Project를 참조합니다.
namespace Biblioteca.Web.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
var Autor = Inject.Resolve<IAutorBO>();
}
}
}
비즈니스 프로젝트 - 나는 여기 (아래 참조) 데이터 프로젝트에 클래스를 AutorDO 가리 키도록 유니티 3의 IoC를 사용합니다. 비즈니스 프로젝트에는 데이터 프로젝트가 표시되지 않습니다.
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
}
}
비즈니스 및 데이터 프로젝트 모두 IoC 구현에 사용되는 모든 Unity 3 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
}
}
알 수 있습니다. 순환 적 종속성을 야기하므로이 방법을 구현할 수 없습니다.
데이터 프로젝트를 참조하는 계약 프로젝트가 있습니다. 하지만 데이터 프로젝트에있는 엔터티 Autor가 필요하기 때문에 "SearchFor"메서드를 사용할 수 없습니다.
비즈니스 및 데이터 모두 엔티티 클래스가 필요하므로 동일한 메소드 서명이 있어야합니다.
웹이 비즈니스 및 비즈니스를 참조하지 않고 Data를 참조하지 않고 IoC를 사용하도록 허용하고 Entity를 매개 변수로 전달할 수있는 다른 방법을 만들 수있는 방법이 필요합니다.
어떤 제안? 나는 이미 세 번째 프로젝트를 만들려고 노력했지만 그것을 작동시킬 수는 없다. Reflection을 사용할 수 있습니까? 가능하다면 어떻게?
나는 어떤 제안을 주셔서 감사합니다.
누구나 그 문제를 어떻게 해결할 수 있는지 알고 있습니까? 그것은 정말로 중요합니다. 왜냐하면 제가 건축을 마무리해야하기 때문입니다. 감사. – Olivertech