/// <summary> /// Tries to loads the OpenRiaServices.DomainServices.Server assembly from the server projects references. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="loggingService">The logging service.</param> private static void LoadOpenRiaServicesServerAssembly(SharedCodeServiceParameters parameters, ILoggingService loggingService) { // Try to load the OpenRiaServices.DomainServies.Server assembly using the one used by the server project // This way we can be sure that codegen works with both signed and unsigned server assembly while // making sure that only a single version is loaded var filename = OpenRiaServices_DomainServices_Server_Assembly; var serverAssemblyPath = parameters.ServerAssemblies.FirstOrDefault(sa => sa.EndsWith(filename)); if (serverAssemblyPath != null) { var serverAssembly = AssemblyUtilities.LoadAssembly(serverAssemblyPath, loggingService); if (serverAssembly != null) { // Since this assembly (OpenRiaServices.DomainServices.Tools) requires the Server assembly to be loaded // before the final call to AssemblyUtilities.SetAssemblyResolver (when the DomainServiceCatalog is instanciated) // we need to setup our assembly resolver with the server assembly in case the server version is signed // but this version is unsigned if (!serverAssembly.GetName().IsSigned()) { loggingService.LogWarning(Resource.ClientCodeGen_SignedTools_UnsignedServer); } } else { loggingService.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Failed_Loading_OpenRiaServices_Assembly, filename, serverAssemblyPath)); } } else { loggingService.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Missing_OpenRiaServices_Reference, filename)); } }
/// <summary> /// Returns the full set of <see cref="Assembly"/> instances from which to build the MEF composition container, /// </summary> /// <param name="compositionAssemblyPaths">Optional set of assembly locations to include.</param> /// <param name="logger"><see cref="ILogger"/> instance to report issues.</param> /// <returns>The set of <see cref="Assembly"/> instances to use.</returns> private static IEnumerable <Assembly> GetCompositionAssemblies(IEnumerable <string> compositionAssemblyPaths, ILogger logger) { HashSet <Assembly> assemblies = new HashSet <Assembly>(); if (compositionAssemblyPaths != null) { foreach (string assemblyPath in compositionAssemblyPaths) { Assembly a = AssemblyUtilities.LoadAssembly(assemblyPath, logger); if (a != null) { // Don't put System assemblies into container if (!a.IsSystemAssembly()) { assemblies.Add(a); } } } } // Add this assembly itself to allow MEF to satisfy our imports assemblies.Add(typeof(ClientCodeGenerationDispatcher).Assembly); return(assemblies); }
/// <summary> /// Does a "reflection only load" of all the reference assemblies for the given <paramref name="assembly"/> /// </summary> /// <param name="assembly">The assembly whose references need to be loaded.</param> /// <param name="assemblySearchPaths">Optional list of folders to search for assembly references.</param> /// <param name="loadedAssemblies">Dictionary to track already loaded assemblies.</param> /// <param name="recursive">If <c>true</c> recursively load references from the references.</param> /// <param name="logger">The optional logger to use to report known load failures.</param> /// <returns><c>true</c> means all loads succeeded, <c>false</c> means some errors occurred and were logged. /// </returns> internal static bool ReflectionOnlyLoadReferences(Assembly assembly, IEnumerable <string> assemblySearchPaths, Dictionary <string, Assembly> loadedAssemblies, bool recursive, ILogger logger) { System.Diagnostics.Debug.Assert(assembly != null, "assembly is required"); System.Diagnostics.Debug.Assert(loadedAssemblies != null, "loadedAssemblies is required"); bool result = true; // Ensure this assembly itself is shown in our loaded list loadedAssemblies[assembly.FullName] = assembly; AssemblyName[] assemblyReferences = assembly.GetReferencedAssemblies(); foreach (AssemblyName name in assemblyReferences) { // We cannot load MSCorLib into an RO load. // Attempting to load the SL version will only return the already loaded MSCorlib if (IsAssemblyMsCorlib(name)) { continue; } Assembly referenceAssembly = null; // It may have been loaded already. If so, assume that means we already // followed down its references. Otherwise, load it and honor the // request to recursively load its references. if (!loadedAssemblies.TryGetValue(name.FullName, out referenceAssembly)) { referenceAssembly = AssemblyUtilities.ReflectionOnlyLoad(name, assemblySearchPaths, loadedAssemblies, logger); // Note: we always put the result into our cache, even for failure. // This prevents us from attempting to load it multiple times loadedAssemblies[name.FullName] = referenceAssembly; if (referenceAssembly != null && recursive) { if (!AssemblyUtilities.ReflectionOnlyLoadReferences(referenceAssembly, assemblySearchPaths, loadedAssemblies, recursive, logger)) { result = false; } } else { // failure to load anything give false return result = false; } } } return(result); }
/// <summary> /// Invoked once to force load all assemblies into an analysis unit /// </summary> private void LoadAllAssembliesAndSetAssemblyResolver() { this._loadedAssemblies = new Dictionary <Assembly, bool>(); foreach (string assemblyName in this._assembliesToLoad) { Assembly assembly = AssemblyUtilities.LoadAssembly(assemblyName, this._logger); if (assembly != null) { // The bool value indicates whether this assembly should be searched for a DomainService this._loadedAssemblies[assembly] = TypeUtility.CanContainDomainServiceImplementations(assembly); } } AssemblyUtilities.SetAssemblyResolver(this._loadedAssemblies.Keys); }
/// <summary> /// Looks at all loaded assemblies and adds DomainServiceDescription for each DomainService found /// </summary> private void AddDomainServiceDescriptions() { foreach (KeyValuePair <Assembly, bool> pair in this._loadedAssemblies) { // Performance optimization: standard Microsoft assemblies are excluded from this search if (pair.Value) { // Utility autorecovers and logs for common exceptions IEnumerable <Type> types = AssemblyUtilities.GetExportedTypes(pair.Key, this._logger); foreach (Type t in types) { if (typeof(DomainService).IsAssignableFrom(t) && TypeDescriptor.GetAttributes(t)[typeof(EnableClientAccessAttribute)] != null) { this.AddDomainServiceType(t); } } } } }