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 は Singleton として登録されます。そして、次のようにコンストラクター注入を実装しました。

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 のコンストラクター インジェクションを実装すると、循環参照が原因でスタック オーバーフロー例外が発生しました。

Unity は循環参照をサポートしていないことを読みました。これを回避する(堅実な)方法はありますか。または、別のアーキテクチャを実装する必要がありますか? もしそうなら、解決策をお勧めできますか?

4

1 に答える 1

1

これが通常行われる方法は、必要なサービスだけを宣言し、それらを ctor 注入することです。すべてを含む「ServiceWrapper」を注入しないでください。必要なものを注入します。コンテナーが型を構築するので、サービスの提供について心配する必要はありません。彼らはちょうどそこにいます。

多くの場合、開発ワークフローは次のようになります。

  1. 新しい依存性注入フィールドを追加する
  2. 既存のセクターを削除
  3. Resharper を使用して ctor を再生成します: alt+ins、ctor を生成します。
于 2013-02-14T10:17:46.767 に答える