我正在开发一个vb.net迁移项目..project有一些核心dll..core dlls根据更新需要重新编写包装类
现有的dll代码:
public abstract class BusinessService : IPayload, IPayload2, IParserContext
现有代码
Public Sub Execute(ByVal pBs As BusinessService, ByVal pExecuteMode As ExecuteModes)
If pExecuteMode = ExecuteModes.AwaitAsynchronous Then
Me.Execute(pBs, Me.AWAIT_TIME_IN_MILLISEC)
Else
mStartTime = Now()
mBsExecuterHelper = New BsExecuterHelper
mBsExecuterHelper.Execute(pBs, pExecuteMode)
End If
End Sub
新的Dll代码:
public class BusinessService<TRequest, TResponse> :
IBusinessService where TRequest : BsRequest, new() where TResponse : BsResponse, new()
{
}
现在我需要将BusinessService作为参数传递给现有代码。我在这里可以帮助我如何将泛型类作为带有多个约束的参数传递
答案 0 :(得分:0)
Public Class BsExecuter
Private WithEvents mAwaitTimer As System.Windows.Forms.Timer
Private Const AWAIT_TIME_IN_MILLISEC As Integer = 50
Private WithEvents mBsExecuterHelper As BsExecuterHelper
Public Delegate Sub CallBackMethod(ByVal pBusinessService As BusinessService, ByVal pException As Exception)
Public Event BsExecuted(ByVal pBsExecuter As BsExecuter, ByVal pBusinessService As BusinessService, ByVal pException As System.Exception)
Private mStartTime, mEndTime As Date
Private mLogger As ILog
Enum ExecuteModes
Synchronous = 1
Asynchronous = 2
AwaitAsynchronous = 3
End Enum
Enum ExecuteStates
NotStarted = 1
Running = 2
Finnished = 3
Cancelled = 4
End Enum
Public Sub Execute(ByVal pBs As BusinessService)
Me.Execute(pBs, ExecuteModes.Synchronous)
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pExecuteMode As ExecuteModes)
If pExecuteMode = ExecuteModes.AwaitAsynchronous Then
Me.Execute(pBs, Me.AWAIT_TIME_IN_MILLISEC)
Else
mStartTime = Now()
mBsExecuterHelper = New BsExecuterHelper
mBsExecuterHelper.Execute(pBs, pExecuteMode)
End If
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pAwaitTimeInMillisec As Integer)
mBusinessService = pBs
mAwaitTimer = New System.Windows.Forms.Timer
mAwaitTimer.Enabled = True
mAwaitTimer.Interval = pAwaitTimeInMillisec
Debug.WriteLine("Called: " & Now().ToString("ss.ffff"))
mAwaitTimer.Start()
End Sub
Private Sub mAwaitTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles mAwaitTimer.Tick
mAwaitTimer = Nothing
Debug.WriteLine("Starts: " & Now().ToString("ss.ffff"))
mStartTime = Now()
mBsExecuterHelper = New BsExecuterHelper
mBsExecuterHelper.Execute(mBusinessService, ExecuteModes.Asynchronous)
mBusinessService = Nothing
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pAddressOfCallbackMethod As CallBackMethod)
Me.Execute(pBs, pAddressOfCallbackMethod, ExecuteModes.Synchronous)
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pAddressOfCallbackMethod As CallBackMethod, ByVal pExecuteMode As ExecuteModes)
mStartTime = Now()
mBsExecuterHelper = New BsExecuterHelper
mBsExecuterHelper.Execute(pBs, pAddressOfCallbackMethod, pExecuteMode)
End Sub
Public Sub Cancel()
mBsExecuterHelper.ExecuteState = ExecuteStates.Cancelled
End Sub
Private Sub mBsExecuterHelper_BsExecuted(ByVal pBusinessService As BusinessService, ByVal pException As System.Exception) Handles mBsExecuterHelper.BsExecuted
mEndTime = Now()
Me.LogBusinessService(pBusinessService)
RaiseEvent BsExecuted(Me, pBusinessService, pException)
End Sub
Private Sub mBsExecuterHelper_ExecuteCallBack(ByVal pBusinessService As BusinessService, ByVal pException As System.Exception) Handles mBsExecuterHelper.ExecuteCallBack
mEndTime = Now()
Me.LogBusinessService(pBusinessService)
End Sub
Private Sub LogBusinessService(ByVal pBusinessService As BusinessService)
If Not (pBusinessService Is Nothing) Then
Dim vLoggString As String = ""
Dim vExecTime As TimeSpan
Dim vExecTimeInSek As Double
mLogger = LogManager.GetLogger(pBusinessService.GetServiceName())
vExecTime = mEndTime.Subtract(mStartTime)
vExecTimeInSek = vExecTime.Milliseconds / 1000
'vLoggString = "Start:" & mStartTime.ToString("HH:mm:ss,ffff") & " End:" & mEndTime.ToString("HH:mm:ss,ffff")
vLoggString = "ExecutionTime:" & vExecTimeInSek.ToString("#####0.0") & "s"
vLoggString &= " User:" & Environment.UserName
vLoggString &= " Request:" & pBusinessService.GetRequestXml()
mLogger.Info(vLoggString)
End If
End Sub
#Region " BsExecuterHelper "
Private Class BsExecuterHelper
#Region "Used by main thread"
Private mThread As Thread
Private mExecuteModes As ExecuteModes
Private mCallBackMethod As CallBackMethod
Shared Sub New()
SharedTimer = New System.Windows.Forms.Timer
SharedTimer.Enabled = True
SharedTimer.Interval = 70
End Sub
Public Event BsExecuted(ByVal pBusinessService As BusinessService, ByVal pException As System.Exception)
Public Event ExecuteCallBack(ByVal pBusinessService As BusinessService, ByVal pException As System.Exception)
Private Sub mPrivateTimerReference_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles mPrivateTimerReference.Tick
mPrivateTimerReference = Nothing
If Not mCallBackMethod Is Nothing Then
RaiseEvent ExecuteCallBack(mBs, mException)
mCallBackMethod(mBs, mException)
Else
RaiseEvent BsExecuted(mBs, mException)
End If
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pExecuteMode As ExecuteModes)
mBs = pBs
mExecuteModes = pExecuteMode
ExecuteState = ExecuteStates.Running
If pExecuteMode = ExecuteModes.Synchronous Then
RunBs()
Else
mThread = New Thread(AddressOf RunBs)
mThread.Name = "BsExecuter"
mThread.IsBackground = True
mThread.Start()
End If
End Sub
Public Sub Execute(ByVal pBs As BusinessService, ByVal pAddressOfCallbackMethod As CallBackMethod, ByVal pExecuteMode As ExecuteModes)
mCallBackMethod = pAddressOfCallbackMethod
Me.Execute(pBs, pExecuteMode)
End Sub
Public Sub Cancel()
ExecuteState = ExecuteStates.Cancelled
End Sub
#End Region
#Region "Used by new sub thread"
Private Sub ServiceExecuted()
If mExecuteModes = ExecuteModes.Synchronous Then
If Not mCallBackMethod Is Nothing Then
RaiseEvent ExecuteCallBack(mBs, mException)
mCallBackMethod(mBs, mException)
Else
RaiseEvent BsExecuted(mBs, mException)
End If
Else
mPrivateTimerReference = SharedTimer
End If
End Sub
Private Sub RunBs()
Dim vException As Exception = Nothing
Try
'Use INAF EbcHandler to mock BS calls and for error handling translation
IKEA.Framework.DomainModel.Context.ServiceContext.EbcHandler.ExecuteBusinessService(mBs)
'mBs.Execute()
Catch e As Exception
vException = e
Finally
If Not ExecuteState = ExecuteStates.Cancelled Then
ExecuteState = ExecuteStates.Finnished
mException = vException
ServiceExecuted()
End If
End Try
End Sub
#End Region
#Region "Shared between the threads"
Private Shared SharedTimer As System.Windows.Forms.Timer
Private mBs As BusinessService
Private mException As System.Exception = Nothing
Private WithEvents mPrivateTimerReference As System.Windows.Forms.Timer
Public Event ExecuteStateChanged()
Private mExecuteState As ExecuteStates = ExecuteStates.NotStarted
Public Property ExecuteState() As ExecuteStates
Get
Return mExecuteState
End Get
Set(ByVal Value As ExecuteStates)
mExecuteState = Value
RaiseEvent ExecuteStateChanged()
End Set
End Property
#End Region
End Class
#End Region
End Class
答案 1 :(得分:0)
假设您希望将Execute
方法设为通用,并且能够接受通用BusinessService
作为输入,则方法签名应如下所示:
Public Sub Execute(Of TRequest As {New, BsRequest}, TResponse As {New, BsResponse})(
ByVal pBs As BusinessService(Of TRequest, TResponse),
ByVal pExecuteMode As ExecuteModes)
End Sub
当然,这需要对您班级中的其他方法进行类似的更改。
您可能还决定让整个班级变得像这样:
Public Class BsExecuter(Of TRequest As {New, BsRequest}, TResponse As {New, BsResponse})
Public Sub Execute(
ByVal pBs As BusinessService(Of TRequest, TResponse),
ByVal pExecuteMode As ExecuteModes)
End Sub
End Class
请注意,在这种情况下,该方法已经是通用的,您不需要在方法上指定泛型约束,因为它们已经为类设置了。
如果您不需要您的方法是通用的,例如,您可能希望您的方法处理特定的BusinessService
(例如BusinessService(Of MyRequest, MyResponse)
),您可以这样做:
假设这些是您的特殊BsRequest
和BsResponse
类:
Public Class MyRequest
Inherits BsRequest
End Class
Public Class MyResponse
Inherits BsResponse
End Class
然后你不需要做任何通用的,只是你可以接受你想要的特定类型:
Public Sub Execute(
ByVal pBs As BusinessService(Of MyRequest, MyResponse),
ByVal pExecuteMode As ExecuteModes)
End Sub