2016-07-18 17 views
10

Korzystanie z odbicia, Jak uzyskać wszystkie typy implementujące określony interfejs w wersji .NET Core? Zauważyłem, że metody dostępne w .NET 4.6 nie są już dostępne.Uzyskiwanie wszystkich typów implementujących interfejs w .NET Core

Na przykład ten kod nie działa.

var type = typeof(IMyInterface); 
var types = AppDomain.CurrentDomain.GetAssemblies() 
    .SelectMany(s => s.GetTypes()) 
    .Where(p => type.IsAssignableFrom(p)); 

Zgłasza błąd The name 'AppDomain' does not exist in the current context.

+2

Jestem pewien, że kod działa dobrze, po prostu nie masz 'AppDomain'. –

+0

@ BlueEyedBehemoth so Jak dołączyć AppDomain? : D –

+0

Do czego jest to potrzebne? Zazwyczaj nie jest to coś, z czym się bałaganisz. –

Odpowiedz

9

można zrobić w ten sposób:

System.Reflection.Assembly ass = System.Reflection.Assembly.GetEntryAssembly(); 

foreach (System.Reflection.TypeInfo ti in ass.DefinedTypes) 
{ 
    if (ti.ImplementedInterfaces.Contains(typeof(yourInterface))) 
    { 
     ass.CreateInstance(ti.FullName) as yourInterface; 
    } 
} 

Jeśli chcesz rodzajów we wszystkich zespołów, po prostu kliknąć na poniższy uzyskać wszystkie referencje i wykonaj ponownie powyżej :)

ass.GetReferencedAssemblies() 
+0

To tylko pobiera typy w jednym zespole, a nie wszystkie załadowane złożenia. –

+1

Skrócone użycie LINQ var typy = Assembly.GetEntryAssembly(). DefinedTypes.Where (ti => ti.ImplementedInterfaces.Contains (typeof (ILogger))). Wybierz (m => m.FullName); –

0

Jeśli chcesz typy we wszystkich złożeniach, po prostu skorzystaj z poniższych instrukcji, aby uzyskać wszystkie odniesienia i powtórz powyższe czynności :)

ass.GetReferencedAssemblies() 
0

Możliwym rozwiązaniem jest poinformowanie użytkownika, kim są obiekty, które implementują go za pomocą [ServiceKnownTypeAttribute], a kiedy potrzebujesz znać typy, które implementują, otrzymuj przez odbicie. Przykład:

public class TypeWithImplementOne : IMyInterface 
{ 
    public string Hi() 
    { 
    return "hi"; 
    } 

} 
public class TypeWithImplementTwo : IMyInterface 
{ 
    public string Hi() 
    { 
    return "hi"; 
    } 
} 
public interface IMyInterface{ 
{ 
    [ServiceKnownType(typeof(TypeWithImplementOne))] 
    [ServiceKnownType(typeof(TypeWithImplementTwo))] 

    string Hi(); 
} 

I można odzyskać typy, które realizowane z:

private IEnumerable<string> GetKnownTypes() 
    { 
     List<string> result = new List<string>(); 

     Type interfaceType = typeof(IMyInterface); 
     IEnumerable<CustomAttributeData> attributes = interfaceType.CustomAttributes 
      .Where(t => t.AttributeType == typeof(ServiceKnownTypeAttribute)); 

     foreach (CustomAttributeData attribute in attributes) 
     { 
      IEnumerable<CustomAttributeTypedArgument> knownTypes = attribute.ConstructorArguments; 
      foreach (CustomAttributeTypedArgument knownType in knownTypes) 
      { 
       result.Add(knownType.Value.ToString()); 
      } 
     } 

     result.Sort(); 
     return result; 
    } 
2

pełny kod, aby dostać wszystko.

public static IEnumerable<T> GetAll() 
{ 
    var assembly = Assembly.GetEntryAssembly(); 
    var assemblies = assembly.GetReferencedAssemblies(); 

    foreach (var assemblyName in assemblies) 
    { 
     assembly = Assembly.Load(assemblyName); 

     foreach (var ti in assembly.DefinedTypes) 
     { 
      if (ti.ImplementedInterfaces.Contains(typeof(T))) 
      { 
       yield return (T)assembly.CreateInstance(ti.FullName); 
      } 
     } 
    }    
} 
1

w .NET 2.0 Rdzeń można znaleźć wszystkie pasujące typów w zespoły, które były znane w czasie kompilacji (nie działa na dynamicznie obciążonych zespołów) jak to:

private static IEnumerable<Type> GetAllTypesOf<T>() 
{ 
    var platform = Environment.OSVersion.Platform.ToString(); 
    var runtimeAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(platform); 

    return runtimeAssemblyNames 
     .Select(Assembly.Load) 
     .SelectMany(a => a.ExportedTypes) 
     .Where(t => typeof(T).IsAssignableFrom(t)); 
} 

ta opiera się na pakiet Microsoft.Extensions.DependencyModel.