ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Prism] DirectoryModuleCatalog
    C#/Prism 2023. 2. 21. 16:49

     

    prism 동적모듈 데브익스프레스 적용 파일.

     

    DevTestClass.cs
    0.03MB

     

     

     


    1.mirror file


    2.참고

    1.mirror file

     

    DynamicModule.cs
    0.01MB
    AddModuleAssm.cs
    0.00MB

     

    App.cs

     protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
    		mDir.Items.AddRange(AddModuleAssm.AddModuleInfo(db.AssmList));    
        }

     

     

     

     

     

    DirectoryModuleCatalog.cs

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using Prism.Properties;
    
    namespace Prism.Modularity
    {
        /// <summary>
        /// Represents a catalog created from a directory on disk.
        /// </summary>
        /// <remarks>
        /// The directory catalog will scan the contents of a directory, locating classes that implement
        /// <see cref="IModule"/> and add them to the catalog based on contents in their associated <see cref="ModuleAttribute"/>.
        /// Assemblies are loaded into a new application domain with ReflectionOnlyLoad.  The application domain is destroyed
        /// once the assemblies have been discovered.
        ///
        /// The directory catalog does not continue to monitor the directory after it has created the initialize catalog.
        /// </remarks>
        public class DirectoryModuleCatalog : ModuleCatalog
        {
            /// <summary>
            /// Directory containing modules to search for.
            /// </summary>
            public string ModulePath { get; set; }
    
            /// <summary>
            /// Drives the main logic of building the child domain and searching for the assemblies.
            /// </summary>
            protected override void InnerLoad()
            {
                if (string.IsNullOrEmpty(this.ModulePath))
                    throw new InvalidOperationException(Resources.ModulePathCannotBeNullOrEmpty);
    
                if (!Directory.Exists(this.ModulePath))
                    throw new InvalidOperationException(
                        string.Format(CultureInfo.CurrentCulture, Resources.DirectoryNotFound, this.ModulePath));
    
                AppDomain childDomain = AppDomain.CurrentDomain;
    
                try
                {
                    List<string> loadedAssemblies = new List<string>();
    
                    var assemblies = (
                                         from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
                                         where !(assembly is System.Reflection.Emit.AssemblyBuilder)
                                            && assembly.GetType().FullName != "System.Reflection.Emit.InternalAssemblyBuilder"
                                            && !String.IsNullOrEmpty(assembly.Location)
                                         select assembly.Location
                                     );
    
                    loadedAssemblies.AddRange(assemblies);
    
                    Type loaderType = typeof(InnerModuleInfoLoader);
    
                    if (loaderType.Assembly != null)
                    {
                        var loader =
                            (InnerModuleInfoLoader)
                            childDomain.CreateInstanceFrom(loaderType.Assembly.Location, loaderType.FullName).Unwrap();
    
                        this.Items.AddRange(loader.GetModuleInfos(this.ModulePath));
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("There was an error loading assemblies.", ex);
                }
            }
    
            private class InnerModuleInfoLoader : MarshalByRefObject
            {
                [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
                internal ModuleInfo[] GetModuleInfos(string path)
                {
                    DirectoryInfo directory = new DirectoryInfo(path);
    
                    ResolveEventHandler resolveEventHandler =
                        delegate (object sender, ResolveEventArgs args) { return OnReflectionOnlyResolve(args, directory); };
    
                    AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += resolveEventHandler;
    
                    Assembly moduleReflectionOnlyAssembly = AppDomain.CurrentDomain.GetAssemblies().First(asm => asm.FullName == typeof(IModule).Assembly.FullName);
                    Type IModuleType = moduleReflectionOnlyAssembly.GetType(typeof(IModule).FullName);
    
                    IEnumerable<ModuleInfo> modules = GetNotAlreadyLoadedModuleInfos(directory, IModuleType);
    
                    var array = modules.ToArray();
                    AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= resolveEventHandler;
                    return array;
                }
    
                private static IEnumerable<ModuleInfo> GetNotAlreadyLoadedModuleInfos(DirectoryInfo directory, Type IModuleType)
                {
                    List<Assembly> validAssemblies = new List<Assembly>();
                    Assembly[] alreadyLoadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic).ToArray();
    
                    var fileInfos = directory.GetFiles("*.dll")
                        .Where(file => alreadyLoadedAssemblies.FirstOrDefault(
                            assembly => String.Compare(Path.GetFileName(assembly.Location),
                            file.Name, StringComparison.OrdinalIgnoreCase) == 0) == null).ToList();
    
                    foreach (FileInfo fileInfo in fileInfos)
                    {
                        try
                        {
                            validAssemblies.Add(Assembly.LoadFrom(fileInfo.FullName));
                        }
                        catch (BadImageFormatException)
                        {
                            // skip non-.NET Dlls
                        }
                    }
    
                    return validAssemblies.SelectMany(assembly => assembly
                                .GetExportedTypes()
                                .Where(IModuleType.IsAssignableFrom)
                                .Where(t => t != IModuleType)
                                .Where(t => !t.IsAbstract)
                                .Select(type => CreateModuleInfo(type)));
                }
    
                private static Assembly OnReflectionOnlyResolve(ResolveEventArgs args, DirectoryInfo directory)
                {
                    Assembly loadedAssembly = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies().FirstOrDefault(
                        asm => string.Equals(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase));
                    if (loadedAssembly != null)
                    {
                        return loadedAssembly;
                    }
                    AssemblyName assemblyName = new AssemblyName(args.Name);
                    string dependentAssemblyFilename = Path.Combine(directory.FullName, assemblyName.Name + ".dll");
                    if (File.Exists(dependentAssemblyFilename))
                    {
                        return Assembly.ReflectionOnlyLoadFrom(dependentAssemblyFilename);
                    }
                    return Assembly.ReflectionOnlyLoad(args.Name);
                }
    
                [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
                internal void LoadAssemblies(IEnumerable<string> assemblies)
                {
                    foreach (string assemblyPath in assemblies)
                    {
                        try
                        {
                            Assembly.ReflectionOnlyLoadFrom(assemblyPath);
                        }
                        catch (FileNotFoundException)
                        {
                            // Continue loading assemblies even if an assembly can not be loaded in the new AppDomain
                        }
                    }
                }
    
                private static ModuleInfo CreateModuleInfo(Type type)
                {
                    string moduleName = type.Name;
                    List<string> dependsOn = new List<string>();
                    bool onDemand = false;
                    var moduleAttribute =
                        CustomAttributeData.GetCustomAttributes(type).FirstOrDefault(
                            cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleAttribute).FullName);
    
                    if (moduleAttribute != null)
                    {
                        foreach (CustomAttributeNamedArgument argument in moduleAttribute.NamedArguments)
                        {
                            string argumentName = argument.MemberInfo.Name;
                            switch (argumentName)
                            {
                                case "ModuleName":
                                    moduleName = (string)argument.TypedValue.Value;
                                    break;
    
                                case "OnDemand":
                                    onDemand = (bool)argument.TypedValue.Value;
                                    break;
    
                                case "StartupLoaded":
                                    onDemand = !((bool)argument.TypedValue.Value);
                                    break;
                            }
                        }
                    }
    
                    var moduleDependencyAttributes =
                        CustomAttributeData.GetCustomAttributes(type).Where(
                            cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleDependencyAttribute).FullName);
    
                    foreach (CustomAttributeData cad in moduleDependencyAttributes)
                    {
                        dependsOn.Add((string)cad.ConstructorArguments[0].Value);
                    }
    
                    ModuleInfo moduleInfo = new ModuleInfo(moduleName, type.AssemblyQualifiedName)
                    {
                        InitializationMode = onDemand ? InitializationMode.OnDemand : InitializationMode.WhenAvailable,
                        Ref = type.Assembly.EscapedCodeBase,
                    };
                    moduleInfo.DependsOn.AddRange(dependsOn);
                    return moduleInfo;
                }
            }
        }
    }

     


    2.참고

    https://learn.microsoft.com/en-us/dotnet/standard/assembly/load-unload

     

    How to: Load and unload assemblies

    The CLR automatically loads .NET assemblies referenced by a program. You can also dynamically load specific assemblies into the current application domain.

    learn.microsoft.com

     

    https://lifeisforu.tistory.com/288

     

    모듈러 응용프로그램 개발

    프리즘 4.1 도움말 번역입니다 모듈러 응용프로그램 개발 모듈러 응용프로그램은 더 큰 응용프로그램으로 통합될 수 있는 ( 모듈이라는 이름을 가진 ) 기능적 유닛들의 집합으로 구성된 응용프

    lifeisforu.tistory.com


     

    728x90

    'C# > Prism' 카테고리의 다른 글

    [Prism] Apply DevExpress Theme to Prism Dialog  (0) 2023.05.18
    [Prism] Ioc, Container, DI  (0) 2023.02.23
    [Prism] Register  (0) 2023.02.07
    [Prism] Navigation view oneTime Instance  (0) 2023.02.01
    [Prism] RegionAdapter  (0) 2023.02.01

    댓글

Designed by Tistory.