views:

35

answers:

1

Hi,

I'm attempting to dynamically register entities and configurations with a context (ef4 code-only)

I would normally do:

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

Where ContactConfig is a class which inherits EntityConfiguration(Of Contact) and Contact is a class which implements an interface IEntity (IEntity is common to all entities).

So... I need to search a namespace (say Project.DB.Client) for all signatures that match:

EntityConfiguration(Of <Class which implements IEntity>)

How can I achieve this?

+1  A: 

Namespace is just a part of object's name. Searching for types which inherit generic class involves much more effort than just filtering by namespace name:

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 function checks if type is inherited from EntityConfiguration(Of T).

FilterTypes function additionally filters types by namespace and returns filtered list a result.

Example: Dim types = FilterTypes("Project.DB.Client", Assembly.GetExecutingAssembly().GetTypes()).

max
Thanks - I'll try that and get back to you.
Basiclife
Worked well, thanks
Basiclife