/// <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);
        }
Пример #4
0
        /// <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);
                        }
                    }
                }
            }
        }