1

我正在尝试使用 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 不支持循环引用。有没有解决这个问题的(可靠的)方法。或者我应该实现不同的架构?如果是这样,你能推荐一个解决方案吗?

4

1 回答 1

1

通常这样做的方式是仅声明您需要的服务并将它们注入 ctor。不要注入只包含所有内容的“ServiceWrapper”。注入你需要的东西。随着容器构建您的类型,您不必担心提供服务。他们会在那里。

开发工作流程通常是这样的:

  1. 添加一个新的依赖注入字段
  2. 删除现有的ctor
  3. 使用 Resharper 重新生成 ctor:alt+ins,生成 ctor。
于 2013-02-14T10:17:46.767 回答