イベントは層間の結合を避けるために推奨される方法であるため、3層アプリケーションの層間の通信の形式としてイベントを使用しようとしています。ただし、MVC Web アプリケーションの場合のように、結果に同期応答が必要な場合のイベントの使用方法を理解できません。以下の例を検討してください
//1. Repository for Employee (Database Tier)
interface IEmployeeRepository
{
//event to signal add complete in repository
public event EventHandler event_EmployeeAdded_To_Repository;
void AddEmployee(Employee emp);
}
public class EmployeeRepository: IEmployeeRepository
{
//implementation of event
public event EventHandler event_EmployeeAdded_To_Repository;
public void AddEmployee(Employee emp)
{
//Save to database
//Fire event to signal add complete in repository
event_EmployeeAdded_To_Repository(null,e);
}
}
//2. Business Tier for Employee
interface IEmployee
{
//event to signal add complete in business tier
public event EventHandler event_EmployeeAdded_To_Entity;
public void AddEmployee();
}
public class Employee : IEmployee
{
public event EventHandler event_EmployeeAdded_To_Entity;
IEmployeeRepository _empRepository;
//constructor injection
public Employee(IEmployeeRepository empRepository)
{
this._empRepository = empRepository;
//Add event handler for the repository event
this._empRepository.event_EmployeeAdded_To_Repository += OnEmployeeAddedToRepository;
}
public void AddEmployee()
{
//Call repository method for adding to database
_empRepository.AddEmployee(this);
}
//Event handler for the repository event
public void OnEmployeeAddedToRepository(Object sender, EventArgs e)
{
//Fire event to signal add complete in business tier
event_EmployeeAdded_To_Entity(null, e);
}
}
//3. Presentation Tier
public class EmployeeController : Controller
{
IEmployee _emp;
//constructor injection
public EmployeeController(IEmployee emp)
{
this._emp = emp;
//Add event handler for business tier event
this._emp.event_EmployeeAdded_To_Entity += OnEmployeeAddedToEntity;
}
//This is an Ajax method call
public ActionResult Add()
{
//Call add method of business tier
_emp.AddEmployee();
//What do I do here ?
}
//Event handler for the business tier event
public void OnEmployeeAddedToEntity(Object sender, EventArgs e)
{
//What do I do here ?
}
}
上記の例では、リポジトリ(データベース層)にイベント「event_EmployeeAdded_To_Repository」を定義し、リポジトリへの追加完了を通知しています。ビジネス層では、このイベントを処理するイベント ハンドラー "OnEmployeeAddedToRepository" を定義しました。「OnEmployeeAddedToRepository」イベント ハンドラは、イベント「event_EmployeeAdded_To_Entity」を発生させます。最後に、プレゼンテーション層で、ビジネス層のイベントを処理するためのイベント ハンドラー "OnEmployeeAddedToEntity" を定義しました。
しかし、コントローラーには、ユーザーに通知する (または別の ajax アクションを呼び出す) ために、(「AddEmployee」が完了した後) 同期的に応答を返す必要があるアクション「追加」があります。イベントを発生させると、制御の流れがアクションからイベント ハンドラーに変わるだけです。
では、このシナリオでイベントをどのように使用しますか?