Первый подход: Сборка A относится к сборке B. Для этого созвездия я узнал, как создать файл .resx для сборки A, который содержит перечисление, определенное в сборке B. Таким же образом, Я сделал так, чтобы файл .resx содержал объект, для которого существует TypeConverter в сборке B.
Однако реальная цель состоит в том, чтобы я сделал без сборки B. И Enum, и TypeConverter должны быть в сборке A. Однако при попытке Visual Studio сообщает об ошибке компиляции. Я подозреваю, что проблема круговая: resgen.exe может получить доступ к моему Enum и моему TypeConverter только после создания сборки A, сборка A может быть создана только после того, как файл .resx был скомпилирован.
Есть ли у кого-нибудь какие-либо идея?
Редактировать
1. Мое перечисление ESecurityContextAttributes
a. ESecurityContextAttributes
реализация:
<Flags>
Public Enum ESecurityContextAttributes As Int32
None = 0
' other values
End Enum
b. ESecurityContextAttributes
значение в файле .resx:
<assembly alias="NDToolsCommon0" name="NDToolsCommon0, Version=5.2.0.1, Culture=neutral, PublicKeyToken=null" />
<data name="TlsStreamInContextAttributes" type="NDTools.Common.WindowsAndInteroperability.ESecurityContextAttributes, NDToolsCommon0">
<value>ReplayDetect, SequenceDetect, Confidentiality, InitStream, AcceptStream</value>
</data>
c. Ошибка для значения ESecurityContextAttributes
:
Ошибка MSB3103. Ungültige ResX-Datei. Der Typ NDTools.Common.WindowsAndInteroperability.ESecurityContextAttributes, NDToolsCommon0, версия = 5.2.0.1, культура = нейтральная, PublicKeyToken = ноль в ленте Daten в Zeile 401, позиция 4, kann nicht gefunden werden. [engli sh: Недопустимый файл Resx. Тип ... не найден.]
2. Мой объект ConfigStringList
a. ConfigStringList
реализация:
<Serializable>
<TypeConverter(GetType(ConfigListTypeConverter(Of String, ConfigStringList)))>
Public NotInheritable Class ConfigStringList
Inherits ConfigBaseList(Of String, ConfigStringList)
Public Sub New()
MyBase.New
End Sub
Public Sub New(ByVal valValues As IEnumerable(Of String))
MyBase.New(valValues)
End Sub
Private Sub New(serializationInfo As SerializationInfo, streamingContext As StreamingContext)
MyBase.New(serializationInfo, streamingContext)
End Sub
End Class
b. ConfigBaseList
реализация:
<Serializable>
Public MustInherit Class ConfigBaseList(Of TItem As {IConvertible, IEquatable(Of TItem)}, TList As {New, Class, IList(Of TItem)})
Inherits List(Of TItem)
Implements ISerializable
Protected Sub New()
MyBase.New()
End Sub
Protected Sub New(ByVal valValues As IEnumerable(Of TItem))
MyBase.New(valValues)
End Sub
Protected Sub New(ByVal valInfo As SerializationInfo, ByVal valContext As StreamingContext)
AddRange(DirectCast((New ConfigListTypeConverter(Of TItem, TList)).ConvertFrom(DirectCast(valInfo.GetValue("Values", GetType(String)), String)), ConfigBaseList(Of TItem, TList)))
End Sub
Friend Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData
info.AddValue("Values", (New ConfigListTypeConverter(Of TItem, TList)).ConvertTo(Me, GetType(String)))
End Sub
End Class
c. ConfigListTypeConverter
реализация:
Public NotInheritable Class ConfigListTypeConverter(Of TItem As {IConvertible, IEquatable(Of TItem)}, TList As {New, Class, IList(Of TItem)})
Inherits TypeConverter
Private ReadOnly _converter As New ConvertibleConverter
Public Sub New()
MyBase.New
End Sub
Public Overrides Function CanConvertTo(context As ITypeDescriptorContext, destinationType As Type) As Boolean
If destinationType.GetType = GetType(Design.Serialization.InstanceDescriptor) Then
Return True
Else
Return MyBase.CanConvertTo(context, destinationType)
End If
End Function
Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
Return sourceType = GetType(String)
End Function
Public Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object) As Object
Dim valuesString As String
valuesString = TryCast(value, String)
If valuesString IsNot Nothing Then
Return _ParseValueString(valuesString)
Else
Return MyBase.ConvertFrom(context, culture, value)
End If
End Function
Public Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
Dim values As TList
Dim ctor As ConstructorInfo
values = TryCast(value, TList)
If values IsNot Nothing AndAlso destinationType = GetType(String) Then
Return String.Join(",", values.Select(Function(dlgValue As TItem) _converter.Write(dlgValue, CultureInfo.InvariantCulture).Replace("\", "\\").Replace(",", "\,")))
ElseIf destinationType = GetType(Design.Serialization.InstanceDescriptor) AndAlso values IsNot Nothing Then
ctor = GetType(TList).GetConstructor({GetType(IEnumerable(Of TItem))})
Return New Design.Serialization.InstanceDescriptor(ctor, {values})
Else
Return MyBase.ConvertTo(context, culture, value, destinationType)
End If
End Function
Public Overrides Function GetProperties(context As ITypeDescriptorContext, value As Object, attributes() As Attribute) As PropertyDescriptorCollection
Return Nothing
End Function
Public Overrides Function GetPropertiesSupported(context As ITypeDescriptorContext) As Boolean
Return False
End Function
Private Function _ParseValueString(ByVal valValues As String) As TList
Dim isSingleBackslash As Boolean
Dim currentPosCtr As Int32
Dim previousPosCtr As Int32
Dim length As Int32
Dim values As TList
values = New TList
Do While currentPosCtr < valValues.Length
If (Not isSingleBackslash AndAlso valValues(currentPosCtr).Equals(","c)) OrElse currentPosCtr = valValues.Length - 1 Then
If currentPosCtr = valValues.Length - 1 Then
length = currentPosCtr - previousPosCtr + 1
Else
length = currentPosCtr - previousPosCtr
End If
values.Add(_converter.ReadAs(Of TItem)(valValues.Substring(previousPosCtr, length).Replace("\,", ",").Replace("\\", "\"), CultureInfo.InvariantCulture))
previousPosCtr = currentPosCtr + 1
End If
If valValues(currentPosCtr).Equals("\"c) Then
isSingleBackslash = Not isSingleBackslash
ElseIf isSingleBackslash Then
isSingleBackslash = False
End If
currentPosCtr += 1
Loop
Return values
End Function
End Class
d. ConfigStringList
в файле .resx:
<assembly alias="NDToolsCommon0" name="NDToolsCommon0, Version=5.2.0.1, Culture=neutral, PublicKeyToken=null" />
<data name="FtpResponseDateTimeFormats" type="NDTools.Common.Programming.ConfigStringList, NDToolsCommon0">
<value>yyyyMMddHHmm,yyyyMMddHHmmss</value>
</data>
e. Ошибка для ConfigStringList
значение:
ошибка MSB3103: Ungültige ResX-Datei. Der Typ NDTools.Common.Programming.ConfigStringList, NDToolsCommon0, версия = 5.2.0.1, культура = нейтральная, PublicKeyToken = ноль в дате Daten в Zeile 401, позиция 4, kann nicht gefunden werden. [engli sh: Недействительный файл Resx. Тип ... не может быть найден.]
Я проверил все пространства имен. Они установлены правильно. То же самое для версии сборки.