我正在尝试使用 Unity 在我的 ASP.NET MVC 项目中实现依赖注入,并希望获得一些关于如何避免循环引用的建议。
在我的工作中,我们曾经实现服务定位器模式,它为应用程序的每个单独服务返回一个单例。
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 和调用方法轻松访问所有服务,例如:
private ServiceWrapper _services = new ServiceWrapper();
public ActionResult Index()
{
List<Product> products = _services.Product.GetProducts();
return View(products);
}
使用 Unity 设置 DI 轻而易举。我在 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 异常。
我读到 Unity 不支持循环引用。有没有解决这个问题的(可靠的)方法。或者我应该实现不同的架构?如果是这样,你能推荐一个解决方案吗?