gpt4 book ai didi

.net - MEF 导入在 Windows 服务中失败

转载 作者:行者123 更新时间:2023-12-03 17:53:12 24 4
gpt4 key购买 nike

我的 Windows 服务中的 MEF 组合存在问题

下面的类是继承自 System.ServiceProcess.ServiceBase 的部分类

Imports System.ServiceProcess

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class svc_EpmsOPCService_6Cylinder_Zone1
Inherits System.ServiceProcess.ServiceBase

'UserService overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
If _catelog IsNot Nothing Then _catelog.Dispose()
If _mefContainer IsNot Nothing Then _mefContainer.Dispose()
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub

' The main entry point for the process
<MTAThread()> _
Shared Sub Main()

#If Not Debug Then
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
ServicesToRun = New System.ServiceProcess.ServiceBase() {New svc_EpmsOPCService_6Cylinder_Zone1}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
#Else
Dim service = New Worker
service.InitWork()
#End If

End Sub

'Required by the Component Designer
Private components As System.ComponentModel.IContainer

' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer.
' Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.ServiceName = "JCB.EpmsOPCService_6Cylinder_Zone1"

End Sub

End Class

Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports Service.Common

Public Class svc_EpmsOPCService_6Cylinder_Zone1

Private _catelog As AssemblyCatalog
Private _mefContainer As CompositionContainer

<Import(GetType(IServiceWorker))>
Private Property ServiceWorker As IServiceWorker

Public Sub New()

' This call is required by the designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call.
Dim catelog As AggregateCatalog = New AggregateCatalog(New DirectoryCatalog("."), New AssemblyCatalog(Reflection.Assembly.GetExecutingAssembly().CodeBase))
_mefContainer = New CompositionContainer(_catelog)
_mefContainer.ComposeParts(Me)

End Sub

Protected Overrides Sub OnStart(ByVal args() As String)
ServiceWorker.InitWork()
End Sub

Protected Overrides Sub OnStop()
ServiceWorker.StopWork()
_mefContainer.Dispose()
End Sub

End Class

我遇到的问题是当 MEF 尝试在 IServiceWorker 上运行组合时属性失败。最初我虽然认为 IServiceWorker未作为 AggregateCatalog 中的可用部件之一通过
Dim catelog As AggregateCatalog = New AggregateCatalog(New DirectoryCatalog("."), New AssemblyCatalog(Reflection.Assembly.GetExecutingAssembly().CodeBase))

为了确认这是一个有效的零件,我使用以下代码将零件集合输出到文本文件中。
For Each p As System.ComponentModel.Composition.Primitives.ComposablePartDefinition In catelog.Parts
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, p.ToString, vbCrLf), Text.Encoding.Unicode)

For Each meta As KeyValuePair(Of String, Object) In p.Metadata
System.IO.File.AppendAllText(compositionErrorLog, String.Concat("Meta Data Key : ", meta.Key, vbCrLf), Text.Encoding.Unicode)
System.IO.File.AppendAllText(compositionErrorLog, String.Concat("Meta Data Val : ", meta.Value.ToString, vbCrLf), Text.Encoding.Unicode)
Next

For Each exp As Primitives.ExportDefinition In p.ExportDefinitions
System.IO.File.AppendAllText(compositionErrorLog, String.Concat("Export Definition Contract Name : ", exp.ContractName, vbCrLf), Text.Encoding.Unicode)
Next

For Each imp As Primitives.ImportDefinition In p.ImportDefinitions
System.IO.File.AppendAllText(compositionErrorLog, String.Concat("Import Definition Contract Name : ", imp.ContractName, vbCrLf), Text.Encoding.Unicode)
Next

System.IO.File.AppendAllText(compositionErrorLog, vbCrLf, Text.Encoding.Unicode)

Next

您可以从下面的摘录中看到 Service_EPMS_OPC_6Cylinder_Zone1.Worker部分工具 IServiceWorker在其 ExportDefinitions
Service.Common.DataAccess.AuditLogger
Export Definition Contract Name : Service.Common.DataAccess.IAuditLogger
Import Definition Contract Name : Service.Common.DataAccess.IDatabaseHelperFactory

Service.Common.DataAccess.DataHelper
Export Definition Contract Name : Service.Common.DataAccess.IDataHelper
Import Definition Contract Name : Service.Common.DataAccess.IDatabaseHelperFactory

Service.Common.DataAccess.SqlDatabaseHelperFactory
Export Definition Contract Name : Service.Common.DataAccess.IDatabaseHelperFactory

Service.Common.Logging.ErrorLogger
Export Definition Contract Name : Service.Common.Logging.ILogger
Import Definition Contract Name : Service.Common.DataAccess.IDataHelper

Service.Common.Network.NetworkAvailability
Export Definition Contract Name : Service.Common.Network.INetworkAvailability
Import Definition Contract Name : Service.Common.DataAccess.IDataHelper
Import Definition Contract Name : Service.Common.Network.IRemoteServiceHost

Service.Common.Network.RemoteServiceHost
Export Definition Contract Name : Service.Common.Network.IRemoteServiceHost


Service.Common.ObjectCreation.EngineBuilder
Export Definition Contract Name : Service.Common.ObjectCreation.IEngineBuilder
Import Definition Contract Name : Service.Common.DataAccess.IDataHelper

Service.Common.Opc.OpcHelper
Export Definition Contract Name : Service.Common.Opc.IOpcHelper

Service_EPMS_OPC_6Cylinder_Zone1.Worker
Export Definition Contract Name : Service.Common.IServiceWorker

Service_EPMS_OPC_6Cylinder_Zone1.ZoneProcess
Export Definition Contract Name : Service.Common.IZoneProcess
Import Definition Contract Name : Service.Common.Logging.ILogger
Import Definition Contract Name : Service.Common.DataAccess.IDataHelper
Import Definition Contract Name : Service.Common.Network.INetworkAvailability
Import Definition Contract Name : Service.Common.ObjectCreation.IEngineBuilder
Import Definition Contract Name : Service.Common.Opc.IOpcHelper
Import Definition Contract Name : Service.Common.DataAccess.IAuditLogger

这是我所期望的 Worker类在类型 IServiceWorker 上导出.我在这个类上注释掉了两个额外的导入,以确保它们不会导致问题。
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports System.Threading
Imports Service.Common
Imports Service.Common.Enums
Imports Service.Common.Logging

<Export(GetType(IServiceWorker))>
Public Class Worker
Implements IServiceWorker

Private _thread As Thread

'<Import(GetType(IZoneProcess))>
'Private Property Processor() As IZoneProcess

'<Import(GetType(ILogger))>
'Private Property Logger() As ILogger

#Region " Service Methods"

''' <summary>
''' Tear down the service
''' </summary>
''' <remarks></remarks>
Public Sub StopWork() Implements IServiceWorker.StopWork
'Tear down the worker thread
If Not _thread Is Nothing Then
If Not _thread.Join(100) Then
_thread.Abort()
End If
End If

End Sub

''' <summary>
''' Initialise the worker thread
''' </summary>
''' <remarks></remarks>
Public Sub InitWork() Implements IServiceWorker.InitWork

Dim objThreadStart As New ThreadStart(AddressOf Me.StartWork)
_thread = New Thread(objThreadStart)
_thread.Start()

End Sub

''' <summary>
''' Start the worker thread functionality
''' </summary>
''' <remarks></remarks>
Private Sub StartWork()

Try
If Not Initialise() Then
Me.StopWork()
End If

Catch ex As Exception
' If Logger IsNot Nothing Then Logger.LogError(My.Settings.ApplicationID, "StartWork", ex.Message, IssueSeverity.Critical)
Me.StopWork()
End Try
End Sub

#End Region

Private Function Initialise() As Boolean

#If DEBUG Then
RunDebugModeComposition()
#End If
'Return Processor.InitialiseApplication()

End Function

Private Sub RunDebugModeComposition()

Try
Dim catelog As AggregateCatalog = New AggregateCatalog(New DirectoryCatalog("."), New AssemblyCatalog(Reflection.Assembly.GetExecutingAssembly().CodeBase))
Dim container As CompositionContainer = New CompositionContainer(catelog)
container.ComposeParts(Me)
Catch ex As CompositionException
Throw New ApplicationException("The composition of the application failed. Pleae check the underlying exception", ex)
End Try

End Sub

End Class

我用下面的代码进一步查询了 Composition 问题
Try
_mefContainer.ComposeParts(Me)
Catch ex As CompositionException
For Each e As CompositionError In ex.Errors
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, "Description : ", e.Description, vbCrLf), Text.Encoding.Unicode)
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, "Message : ", e.Exception.Message, vbCrLf), Text.Encoding.Unicode)
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, "Stack Trace : ", e.Exception.StackTrace, vbCrLf), Text.Encoding.Unicode)

If e.Exception.InnerException IsNot Nothing Then
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, "Message : ", e.Exception.InnerException.Message, vbCrLf), Text.Encoding.Unicode)
System.IO.File.AppendAllText(compositionErrorLog, String.Concat(vbCrLf, "Stack Trace : ", e.Exception.InnerException.StackTrace, vbCrLf), Text.Encoding.Unicode)
End If

Next
End Try

这个游戏我在文本文件中的以下输出
Description : Cannot set import 'Service_EPMS_OPC_6Cylinder_Zone1.svc_EpmsOPCService_6Cylinder_Zone1.ServiceWorker (ContractName="Service.Common.IServiceWorker")' on part 'Service_EPMS_OPC_6Cylinder_Zone1.svc_EpmsOPCService_6Cylinder_Zone1'.

Message : The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) No exports were found that match the constraint:
ContractName Service.Common.IServiceWorker
RequiredTypeIdentity Service.Common.IServiceWorker


Stack Trace :

现在我不确定的是为什么 IServiceWorker ComposeParts 未提取 MEF 目录零件集合中的导出.据我所知,Worker 类上的 Export 属性应该与 ServiceWorker 上的 Import 匹配。房产在 svc_EpmsOPCService_6Cylinder_Zone1
知道为什么这个导入不起作用吗?

编辑:
我重构了代码,以便将 'Worker' 类作为一个具体实现调用,然后在 'Worker' 类中进行组合,一切正常。
是否存在不能从继承自“System.ServiceProcess.ServiceBase”的 Windows 服务组件组合 MEF 部分的限制?

最佳答案

迟到了,但我想知道这个问题是否与 Windows 如何注册和维护服务有关。我相信 SCM 或其他一些后端服务组件在注册服务时会锁定资源。

我不认为这是 Service 基类本身的问题,它似乎并不太奇怪,它不是静态的,它只是扩展了 Component 等。相反,我敢打赌它与服务本身有关,并且资源管理。

对于咧嘴笑和傻笑,您是否在 MEF DirectoryCatalog 中使用了 ShadowCopy?如果你不是,我想知道它是否会有所帮助......其中一些是猜测,因为我没有时间设置我自己的测试台,但这是从 MEF 和服务分别的经验中得到的有根据的猜测。

关于.net - MEF 导入在 Windows 服务中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15662271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com