내 ASP.NET MVC 프로젝트에서 Unity를 사용하여 종속성 삽입을 구현하려고 시도하고 순환 참조를 피하는 방법에 대한 조언이 필요합니다.Unity - 순환 참조를 피하는 방법은 무엇입니까?
제 업무에서 우리는 응용 프로그램의 개별 서비스마다 싱글 톤을 반환하는 서비스 로케이터 패턴을 구현했습니다. 유니티는 바람이었다 사용하여 DI 설정
private ServiceWrapper _services = new ServiceWrapper();
public ActionResult Index()
{
List<Product> products = _services.Product.GetProducts();
return View(products);
}
:
public class ServiceWrapper
{
private UserService _userService;
private ProductService _productService;
public UserService User
{
if(_userService == null)
{
_userService = new UserService();
}
return _userService;
}
public ProductService Product
{
if(_productService == null)
{
_productService = new ProductService();
}
return _productService;
}
}
그런 다음 컨트롤러에서, 당신은 쉽게 같은 방법을 ServiceWrapper를 인스턴스화하고 호출하여 모든 서비스에 액세스 할 수 있습니다. 그래서 같은 위해 Application_Start() (의 Global.asax)에서 컨테이너를 작성 :
var container = new UnityContainer();
container.RegisterType<IUserService, UserService>(new ContainerControlledLifetimeManager());
container.RegisterType<IProductService, ProductService>(new ContainerControlledLifetimeManager());
container.RegisterType<IServiceWrapper, ServiceWrapper>(new ContainerControlledLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
ServiceWrapper는 싱글로서 등록된다. 그리고 생성자 주입을 다음과 같이 구현했습니다 :
public class ProductController: Controller
{
private IServiceWrapper _services;
public ProductController(IServiceWrapper services)
{
_services = services;
}
public ActionResult Index()
{
List<Product> products = _services.Products.GetProducts();
return View(products);
}
그 것이 아름답게 작동했습니다. 그러나 그 때 나는 문제를 건너왔다.
우리는 당신이 쉽게과 같이, 다른 내에서 다른 서비스에 액세스 할 수 있도록 또한 ServiceWrapper를 포함하는 속성을 가지고 모든 서비스를 원하는 :
public class ProductService
{
private IServiceWrapper _services;
public ProductService(IServiceWrapper services)
{
_services = services;
}
public IServiceWrapper Services { get { return _services; } }
}
을하지만 난의 생성자 주입을 구현하는 경우 개별 서비스에서 ServiceWrapper를 사용하면 순환 참조로 인해 stackoverflow 예외가 발생합니다.
유니티는 순환 참조를 지원하지 않는다고 읽었습니다. 이것 주위에 (단단한) 방법이 있나. 아니면 다른 아키텍처를 구현해야합니까? 그렇다면 솔루션을 추천 해 주시겠습니까?
아니요 아니요. imho 서비스 로케이터는 LOB 응용 프로그램에서 사용하면 안됩니다. 많은 서비스를 사용하여 수업을 찾으면 일반적으로 너무 크며 리팩토링해야합니다. 래퍼를 사용하면 앞으로 유지 보수 문제 만 해결할 수 있습니다. – jgauffin
[Clean Code Talks : Singletons and Global State] (http://www.youtube.com/watch?v=-FRm3VPhseI) –
Mark Seeman의 [Dependency Injection in .NET]에 대한 책 (http : //www.manning .com/seemann /). 특히 패턴 및 반 패턴 섹션을 읽을 가치가 있습니다. –