VB.Net Поиск пространства имен для универсального типа (Reflection) - PullRequest
1 голос
/ 27 сентября 2010

Я пытаюсь динамически зарегистрировать объекты и конфигурации с контекстом (только для кода ef4)

Я бы обычно делал:

Private Shared Sub ConfigureDatabase(ByRef Builder As ContextBuilder(Of ContextExtension))
  'Load configurations for each of the tables (Entity sets) in our database...
  ConfigureEntity(Builder, New ContactConfig)
End Sub

 Private Shared Sub ConfigureEntity(Of T)(ByRef Builder As ContextBuilder(Of ContextExtension), ByVal config As EntityConfiguration(Of T), ByVal setName As String)
    'Register the entity configuration with the builder
    Builder.Configurations.Add(config)

    'Register the entity set name with the builder
    Builder.RegisterSet(Of T)(setName)
End Sub

Где ContactConfig - это класс, который наследует EntityConfiguration(Of Contact), а Contact - это класс, который реализует интерфейс IEntity (IEntity является общим для всех объектов).

Итак ... Мне нужно найти в пространстве имен (скажем, Project.DB.Client) все сигнатуры, которые соответствуют:

EntityConfiguration(Of <Class which implements IEntity>)

Как мне этого добиться?

1 Ответ

1 голос
/ 27 сентября 2010

Пространство имен - это только часть имени объекта.Поиск типов, которые наследуют универсальный класс, требует гораздо больше усилий, чем простая фильтрация по имени пространства имен:

Private Function CheckType(ByVal type As Type) As Boolean
    If (type Is GetType(Object)) Then ' object hierarhy root reached'
        Return False
    End If
    If (type.IsGenericType) Then
        ' inherits from some generic type'
        Dim parameters = type.GetGenericArguments()
        ' check if it has generic 1 parameter'
        If parameters.Length = 1 Then
            ' check if generic parameter is defined'
            If Not (parameters(0).FullName Is Nothing) Then
                ' check if parameter implements IEntity'
                If GetType(IEntity).IsAssignableFrom(parameters(0)) Then
                    ' check if it is EntityConfiguration(Of T)'
                    If type Is GetType(EntityConfiguration(Of )).MakeGenericType(parameters) Then
                        Return True
                    End If
                End If
            End If
        End If
    End If
    Return CheckType(type.BaseType)
End Function

Function FilterTypes(ByVal nameSpaceName As String, ByVal types As IEnumerable(Of Type)) As List(Of Type)
    Dim result As New List(Of Type)
    ' append . to namespace name'
    nameSpaceName = nameSpaceName + "."
    For Each type As Type In types
        ' we do not need abstract classes, wont be able to create their instances anyway'
        If (type.IsClass And Not type.IsAbstract And
             type.FullName.StartsWith(nameSpaceName)) Then
            ' check if type is inherited from EntityConfiguration(Of T)'
            If (CheckType(type)) Then
                result.Add(type)
            End If
        End If
    Next
    Return result
End Function

CheckType функция проверяет, унаследован ли тип от EntityConfiguration(Of T).

FilterTypesфункция дополнительно фильтрует типы по пространству имен и возвращает отфильтрованный список результат.

Пример: Dim types = FilterTypes("Project.DB.Client", Assembly.GetExecutingAssembly().GetTypes()).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...