/// <summary> /// Create an instance of RunspaceConfiguration type implemented from an assembly. /// </summary> /// <param name="assemblyName">Assembly name from which to find runspace configuration implementation</param> /// <returns>Runspace configuration instance created</returns> /// <exception cref="System.ArgumentNullException"> /// Exception thrown when <paramref name="assemblyName"/> is null or empty. /// </exception> /// <!-- /// This is a RunspaceConfiguration factory function which will create an instance /// of default RunspaceConfiguration-derived type, whose name is decided by an /// assembly attribute in the assembly specified. /// --> public static RunspaceConfiguration Create(string assemblyName) { if (String.IsNullOrEmpty(assemblyName)) { throw PSTraceSource.NewArgumentNullException("assemblyName"); } // If this assembly can't be loaded, Assembly.Load will throw an exception. // Just let the exception bubble up. Assembly assembly = null; foreach (Assembly asm in ClrFacade.GetAssemblies()) { if (string.Equals(asm.GetName().Name, assemblyName, StringComparison.OrdinalIgnoreCase)) { assembly = asm; break; } } if (assembly == null) { assembly = Assembly.Load(new AssemblyName(assemblyName)); } return(Create(assembly)); }
private Assembly ResolveAssemblyNameInLoadedAssemblies(string assemblyName, bool fullName) { Assembly result = null; #if false // This should be re-enabled once the default assembly list contains the // assemblies referenced by the S.M.A.dll. // First we need to get the execution context from thread-local storage. ExecutionContext context = System.Management.Automation.Runspaces.LocalPipeline.GetExecutionContextFromTLS(); if (context != null) { context.AssemblyCache.GetAtKey(assemblyName, out result); } #else foreach (Assembly a in ClrFacade.GetAssemblies()) { AssemblyName aName = null; try { aName = a.GetName(); } catch (System.Security.SecurityException) { continue; } string nameToCompare = fullName ? aName.FullName : aName.Name; if (string.Equals(nameToCompare, assemblyName, StringComparison.Ordinal)) { return(a); } } #endif return(result); }
internal static Type ResolveTypeNameWithContext(TypeName typeName, out Exception exception, Assembly[] assemblies, TypeResolutionState typeResolutionState) { ExecutionContext context = null; exception = null; if (typeResolutionState == null) { // Usings from script scope (and if no script scope, fall back to default 'using namespace system') context = LocalPipeline.GetExecutionContextFromTLS(); typeResolutionState = TypeResolutionState.GetDefaultUsingState(context); } // We can do the cache lookup only if we don't define type in the current scope (cache would be invalid in this case). var result = typeResolutionState.ContainsTypeDefined(typeName.Name) ? null : TypeCache.Lookup(typeName, typeResolutionState); if (result != null) { return(result); } if (typeName.AssemblyName != null) { result = ResolveAssemblyQualifiedTypeName(typeName, out exception); TypeCache.Add(typeName, typeResolutionState, result); return(result); } // Simple typename (no generics, no arrays, no assembly name) // We use the following search order, using the specified name (assumed to be fully namespace qualified): // // * Search scope table (includes 'using type x = ...' aliases) // * Built in type accelerators (implicit 'using type x = ...' aliases that are effectively in global scope // * typeResolutionState.assemblies, which contains: // - Assemblies with PS types, added by 'using module' // - Assemblies added by 'using assembly'. // For this case, we REPORT ambiguity, since user explicitly specifies the set of assemblies. // * All other loaded assemblies (excluding dynamic assemblies created for PS defined types). // IGNORE ambiguity. It mimics PS v4. There are two reasons: // 1) If we report ambiguity, we need to fix our caching logic accordingly. // Consider this code // Add-Type 'public class Q {}' # ok // Add-Type 'public class Q { }' # get error about the same name // [Q] # we would get error about ambiguous type, because we added assembly with duplicated type // # before we can report TYPE_ALREADY_EXISTS error. // // Add-Type 'public class Q2 {}' # ok // [Q2] # caching Q2 type // Add-Type 'public class Q2 { }' # get error about the same name // [Q2] # we don't get an error about ambiguous type, because it's cached already // 2) NuGet (VS Package Management console) uses MEF extensibility model. // Different assemblies includes same interface (i.e. NuGet.VisualStudio.IVsPackageInstallerServices), // where they include only methods that they are interested in the interface declaration (result interfaces are different!). // Then, at runtime VS provides an instance. Everything work as far as instance has compatible API. // So [NuGet.VisualStudio.IVsPackageInstallerServices] can be resolved to several different assemblies and it's ok. // * User defined type accelerators (rare - interface was never public) // // If nothing is found, we search again, this time applying any 'using namespace ...' declarations including the implicit 'using namespace System'. // We must search all using aliases and REPORT an error if there is an ambiguity. // If this is TypeDefinition we should not cache anything in TypeCache. if (typeName._typeDefinitionAst != null) { return(typeName._typeDefinitionAst.Type); } if (context == null) { context = LocalPipeline.GetExecutionContextFromTLS(); } // Use the explicitly passed-in assembly list when it's specified by the caller. // Otherwise, retrieve all currently loaded assemblies. var assemList = assemblies ?? ClrFacade.GetAssemblies(typeResolutionState, typeName); var isAssembliesExplicitlyPassedIn = assemblies != null; result = CallResolveTypeNameWorkerHelper(typeName, context, assemList, isAssembliesExplicitlyPassedIn, typeResolutionState, out exception); if (result != null) { TypeCache.Add(typeName, typeResolutionState, result); return(result); } if (exception == null) { foreach (var ns in typeResolutionState.namespaces) { var newTypeNameToSearch = ns + "." + typeName.Name; newTypeNameToSearch = typeResolutionState.GetAlternateTypeName(newTypeNameToSearch) ?? newTypeNameToSearch; var newTypeName = new TypeName(typeName.Extent, newTypeNameToSearch); #if CORECLR if (!isAssembliesExplicitlyPassedIn) { // We called 'ClrFacade.GetAssemblies' to get assemblies. That means the assemblies to search from // are not pre-defined, and thus we have to refetch assembly again based on the new type name. assemList = ClrFacade.GetAssemblies(typeResolutionState, newTypeName); } #endif var newResult = CallResolveTypeNameWorkerHelper(newTypeName, context, assemList, isAssembliesExplicitlyPassedIn, typeResolutionState, out exception); if (exception != null) { break; } if (newResult != null) { if (result == null) { result = newResult; } else { exception = new AmbiguousTypeException(typeName, new string[] { result.FullName, newResult.FullName }); result = null; break; } } } } if (exception != null) { // AmbiguousTypeException is for internal representation only. var ambiguousException = exception as AmbiguousTypeException; if (ambiguousException != null) { exception = new PSInvalidCastException("AmbiguousTypeReference", exception, ParserStrings.AmbiguousTypeReference, ambiguousException.TypeName.Name, ambiguousException.Candidates[0], ambiguousException.Candidates[1]); } } if (result != null) { TypeCache.Add(typeName, typeResolutionState, result); } return(result); }
/// <summary> /// Get the path of reference assembly where the type is declared. /// </summary> private static string GetReferenceAssemblyPathBasedOnType(Type type) { string refAsmFileName = PathType.GetFileName(ClrFacade.GetAssemblies(type.FullName).First().Location); return(PathType.Combine(s_netcoreAppRefFolder, refAsmFileName)); }