/// <summary> /// サービスメソッド実行 /// </summary> /// <typeparam name="TResult">戻り値の型</typeparam> /// <param name="expression">実行するメソッド(および引数)</param> /// <param name="userInfoModel">ユーザー情報</param> /// <returns>戻り値</returns> public TResult InvokeService <TResult>(Expression <Func <TService, TResult> > expression, UserInfoModel userInfoModel) { TResult result; // トランザクション対象であるかチェックする var method = (MethodCallExpression)(expression.Body); var name = method.Method.Name; object[] attributes = method.Method.GetCustomAttributes(typeof(TransactionStart), false); if (attributes != null && attributes.Length != 0) { this._IsTransaction = true; } else { this._IsTransaction = false; } // サービスにユーザー情報を設定する this._Service.UserInfoModel = userInfoModel; // SaveChangesファンクションをセットする this._Service.SaveChangeFunc = () => this.SaveChangeFunc(); // メッセージを設定する this._Service.ServiceMessage = new ServiceMessage(); // 開始ログを出力する this._Log.Debug(string.Format("method={0} Start. Transaction={1}.", name, this._IsTransaction.ToString())); // 実行するサービスのメソッドを取得する Func <TService, TResult> serviceMethod = expression.Compile(); // トランザクション開始 if (this._IsTransaction) { using (this._Tran = this._DbContext.Database.BeginTransaction()) { try { // サービスのメソッドを実行する result = serviceMethod.Invoke(this._Service); // コミット this._Tran.Commit(); } catch (Exception ex) { // ここではDbUpdateConcurrencyException や DbUpdateExceptionは発生しない想定 // 上記2つのExceptionは、SaveChangeFuncメソッド内で処理する _Log.Error(ex); // ロールバック this._Tran.Rollback(); throw ex; } } } else { // サービスのメソッドを実行する result = serviceMethod.Invoke(this._Service); } // 終了ログを出力する this._Log.Debug(string.Format("method={0} End. Transaction={1}.", name, this._IsTransaction.ToString())); return(result); }