在我的 app/services 目錄中,我有一堆服務,每個服務都有一個初始化方法和一個perform不帶引數的公共方法。
顯示結構的簡單示例服務可能如下所示:
module Users
class CreateService
def initialize(name)
@name = name
end
def perform
# code to create the user
end
end
我的目標是向我的應用程式添加跟蹤,以便我可以跟蹤我的每個服務何時被呼叫,而無需顯著修改每個服務的代碼。最后,我希望做到這一點,以便當我的任何服務呼叫它的perform()方法時,自動生成跟蹤。
我相信這應該可以使用 ActiveSupport::Callbacks 來實作,類似于 ActiveJob 讓我們為我們的作業定義,比如說,around_perform 回呼。我試圖創建一個可以包含在我的服務中的關注點,它可以檢測所需的行為
module Traceable
extend ActiveSupport::Concern
include ActiveSupport::Callbacks
included do
include ActiveSupport::Callbacks
define_callbacks :perform
set_callback :perform, :around, lambda { |r, block|
puts "start the trace"
result = block.call
puts "end the trace"
}
end
end
但是,在考慮了這個問題之后,我想定義的回呼(所有服務的統一)仍然沒有被呼叫。我怎樣才能使這項作業?謝謝!
參考:
https://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html
https://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html
https://edgeapi.rubyonrails.org/classes/ ActiveJob/Callbacks/ClassMethods.html#method-i-around_performaround_perform (查看類方法的原始碼)
uj5u.com熱心網友回復:
最干凈的方法是使用prepended。
它看起來像這樣:
module Traceable
extend ActiveSupport::Concern
prepended do
include ActiveSupport::Callbacks
define_callbacks :trace
set_callback :trace, :around do |_r, block|
puts "start the trace"
block.call
puts "end the trace"
end
end
def perform
run_callbacks :trace do
super
end
end
end
module Users
class CreateService
prepend Traceable
attr_accessor :name
def initialize(name)
@name = name
end
def perform
# code to create the user
puts "perform"
end
end
end
該鏈接有更多詳細資訊。服務中的prepend意味著首先會在模塊Users::CreateService.perform中查找它的定義。Traceable這允許Traceable包裝perform回呼。
由于我們使用prepend而不是include在服務中,我們需要在'塊內呼叫define_callbacks和。set_callbackActiveSupport::Concernprepended
如果您是服務中prepend的Traceable模塊,則您實際上不需要callbacks或根本不需要concerns。該Traceable模塊可能就是這樣,它會產生相同的結果:
module Traceable
def perform
puts "before"
super
puts "after"
end
end
module Users
class CreateService
prepend Traceable
...
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/460268.html
