2

新しいソリューションで StructureMap などの IoC コンテナーを使用しようとしています。ソリューション プロジェクトは次のとおりです。

  • デスクトップ UI
  • Desktop.Models
  • Desktop.Views
  • Desktop.プレゼンター
  • ビジネスの論理
  • ビジネスオブジェクト
  • データアクセス

Desktop.Models、BusinessLogic、および DataAccess はすべて BusinessObjects への参照を持っています。

Desktop.UI プロジェクトは、DI を構成する必要があるエントリ ポイントになりますが、DI のためだけに DataAccess への参照を追加したくありません。

SO でこれらの行に沿って他のいくつかの質問を見てきましたが、1 つの答えは、関連するプロジェクトを参照する IoC 用の別のプロジェクトを作成し、次に Desktop.UI から IoC プロジェクトを参照することでした。ただし、Desktop.UI では、ビューのプレゼンターをインスタンス化するために DI を構成する必要があるため、別のプロジェクトが機能するかどうかはわかりません。

Registry クラスを定義し、StructureMap スキャン機能を使用して Registry クラスを自動検出する基本的な例をいくつか見てきました。私が最初に考えたのは、これらのレジストリ クラスを構成対象のプロジェクトに配置することでしたが、その結果、すべてのプロジェクトが StructureMap を参照しなければならなくなりました。

階層化されたアプリケーションで DI を設定するための推奨されるアプローチは何ですか?

4

2 に答える 2

1

WindowsForms の場合、IoC 用の別のプロジェクトがあります。私はそれをCompositionRootと呼んでいます。

CompositionRoot(スタートアップ プロジェクト)のエントリ ポイント:

public static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        BootsTrapper.Boot();

        using (var mainForm = ObjectFactory.GetInstance<IPresenter<IMainView>>())
        {
            Application.Run((Form)mainForm.CurrentView);
        }
    }
}

BootsTrapper登録を担当し、 の一部ですCompositionRoot

MainViewPresenter は最初のフォームを表示します。MainViewPresenter は、IMainViewPresenterFacade抽象プレゼンター ファクトリを含むファサード サービスを使用して、他のフォームを表示できます。

public class MainViewPresenter : Presenter<IMainView>
{
    readonly IArticleRepository _articlesRepository;
    readonly IMainViewPresenterFacade _presenterFactory;
    readonly IUnitOfWork _unitOfWork;

    public MainViewPresenter(IMainView currentView, IArticleRepository articlesRepository, IUnitOfWork unitOfWork,
                             IMainViewPresenterFacade presenterFactory)
        : base(currentView, unitOfWork)
    {
        _articlesRepository = articlesRepository;
        _unitOfWork = unitOfWork;
        _presenterFactory = presenterFactory;

        Ensure.That(articlesRepository).IsNotNull();
        Ensure.That(presenterFactory).IsNotNull();

        CurrentView.DetailsClick += View_DetailsClick;
        CurrentView.CloseClick += ViewCloseClick;
        CurrentView.CreateClick += View_CreateClick;
        CurrentView.DeleteClick += View_DeleteClick;

        CurrentView.BindModel(_articlesRepository.GetAll().Select(x => new ArticleViewModel { Id = x.ArticleId, Name = x.Description }));
    }

    public override void Dispose()
    {
        base.Dispose();

        CurrentView.DetailsClick -= View_DetailsClick;
        CurrentView.CloseClick -= ViewCloseClick;
        CurrentView.CreateClick -= View_CreateClick;
        CurrentView.DeleteClick -= View_DeleteClick;
    }

    void View_DeleteClick(object sender, EventArgs e)
    {
        var selectedArticle = CurrentView.GetSelectedArticle();
        var article = _articlesRepository.GetById(selectedArticle.Id);
        _articlesRepository.Delete(article);
        _unitOfWork.Commit();
    }

    void View_CreateClick(object sender, EventArgs e)
    {
        using (var createPresenter = _presenterFactory.CreateCreatePresenter())
        {
            ShowDialog(createPresenter.CurrentView, CurrentView);
        }
    }

    void ViewCloseClick(object sender, EventArgs e)
    {
        CurrentView.Close();
    }

    void View_DetailsClick(object sender, EventArgs eventArgs)
    {
        var article = CurrentView.GetSelectedArticle();

        if (article == null) return;

        using (var detailPresenter = _presenterFactory.CreateDetailPresenter(article))
        {
            ShowDialog(detailPresenter.CurrentView, CurrentView);
        }
    }
}

私のSimpleMVPプロ​​ジェクトまたはこの質問依存性注入とコンソールアプリケーションのプロジェクト構造を見て、さらに質問してください:)

于 2012-04-15T15:05:40.350 に答える
1

私の経験では、サーバー側のコード全体で 1 つの形式の依存性注入を使用し、クライアント側のコードで 1 つの形式を使用したことがわかりました。たとえば、[ため息] 私が最近取り組んでいた WinForms プロジェクトでは、サーバー側 (ビジネス ロジック、データ アクセス) で Unity を使用し、クライアント側でスマート クライアント ソフトウェア ファクトリ (独自の形式の DI を含む winforms の MVP フレームワーク) を使用しました。したがって、あなたの例では、アプリケーションのすべてのレイヤーで DI フレームワークを機能させるのに苦労している場合、それはそうすべきではないためです。クライアント用とサーバー用の 2 つの形式の DI が必要な場合があるでしょう。

これに加えて、ほとんどの DI フレームワークでは、構成ファイルで依存関係をブートストラップできると言っているのは正しいと思います。構成ファイルは、どのアセンブリに含まれているかなど、依存関係に関するすべてをフレームワークに伝えます。これは、IoC コンテナーをインスタンス化するプロジェクト内の実際のプロジェクトを参照する必要がないことを意味します。フレームワーク プロジェクトの私の例では、IoC コンテナーをインスタンス化し、構成ファイルからすべての依存関係を読み取るシングルトンがあります。

ここにあなたのためのいくつかのリンクがあります:

その一部が役立つことを願っています!

よろしく、

ジェームズ

于 2012-04-15T11:11:47.930 に答える