MVP を使用して、構築と依存性注入の通常の順序は何ですか。
通常、ビューごとにプレゼンターを作成し、ビューをコンストラクターでプレゼンターに渡します。しかし、次の場合はどうでしょう。
- 複数のビューがイベントをリッスンする必要があるサービス。
- 複数のビューがすべて同じデータ モデル キャッシュを指している。
ユーザーのクリックから、サーバーからサービスに返されるデータまでの通常の情報の流れを誰かが表示できますか?
これが私がすることです:
まず、次のインターフェイスを定義します。
public interface IView<TPresenter>
{
TPresenter Presenter { get; set; }
}
public interface IPresenter<TView, TPresenter>
where TView : IView<TPresenter>
where TPresenter : IPresenter<TView, TPresenter>
{
TView View { get; set; }
}
次に、この抽象プレゼンター クラス:
public abstract class AbstractPresenter<TView, TPresenter> : IPresenter<TView, TPresenter>
where TView : IView<TPresenter>
where TPresenter : class, IPresenter<TView, TPresenter>
{
protected TView view;
public TView View
{
get { return this.view; }
set
{
this.view = value;
this.view.Presenter = this as TPresenter;
}
}
}
ビューは、コンストラクターではなくプロパティを介して注入され、セッターで双方向の影響を可能にします。安全なキャストが必要であることに注意してください...
次に、私の具体的なプレゼンターは次のようなものです:
public class MyPresenter : AbstractPresenter<IMyView, MyPresenter>
{
//...
}
IMyView
を実装する場所IView
。具体的なビュー タイプ (例: MyView
) が存在する必要がありますが、それを解決するのはコンテナーです。
MyPresenter
一時的な動作で、型をそれ自体としてコンテナーに登録します。MyView
として登録します。IMyView
MyPresenter
、コンテナに a を要求します。MyPresenter
AbstractPresenter.View
ます。ビューとプレゼンターの両方に他の依存関係 (サービス、リポジトリ) を挿入できます。ただし、説明したシナリオでは、ビューではなく、サービスとキャッシュをプレゼンターに挿入することをお勧めします。
interface IEmployee
{
int EmployeeId {get;}
string FirstName {get;}
string LastName {get;}
}
interface IEmployeeRepository
{
void SaveEmployee(IEmployee employee);
IEmployee GetEmployeeById(int employeeId);
IEmployee[] Employees { get; }
}
interface IEmployeeView
{
event Action<IEmployee> OnEmployeeSaved;
}
interface IEmployeeController
{
IEmployeeView View {get;}
IEmployeeRepository Repository {get;}
IEmployee[] Employees {get;}
}
partial class EmployeeView: UserControl, IEmployeeView
{
public EmployeeView()
{
InitComponent();
}
}
class EmployeeController:IEmployeeController
{
private IEmployeeView view;
private IEmployeeRepository repository;
public EmployeeController(IEmployeeView view, IEmployeeRepository repository)
{
this.repository = repository;
this.view = view;
this.view.OnEmployeeSaved+=new Action<IEmployee>(view_OnEmployeeSaved);
}
void view_OnEmployeeSaved(IEmployee employee)
{
repository.SaveEmployee(employee);
}
public IEmployeeView View
{
get
{
return view;
}
}
public IEmployeeRepository Repository
{
get
{
return repository;
}
}
public IEmployee[] Employees
{
get
{
return repository.Employees;
}
}
}