zoukankan      html  css  js  c++  java
  • ESB相关技术入门

    ESBEnterprise Service Bus)企业系统总线,主要是的作用是通过这个基础架构将企业内部的服务组织在一起,服务与服务之间可以相互进行调用,并且提供一种负载均衡机制。当然其中还是有了很多技术打算做成一个系列的文章,本次并没有打算直接讲解ESB整体的架构思想,而是将它进行了拆分,讲诉了其中一些使用的技术点。通过这些点的拆分,我们可以了解其中所使用的技术并进行自我充电,在后续我们将会介绍一下具体的架构思想。

           本期主要的技术点如下:

    1.        FileSystemWatcher:文件侦听类。

    2.        CodeDomProvider:创建和检索代码类。

    3.        Appdomain:应用程序域。

    4.        MarshalByRefObject:跨应用程序域边界访问对象。

     

    1.      FileSystemWatcher

    定义:侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。

    具体实现:

            public void RegeditFileSystemWatcher(string filePath, string filter)

            {

                FileSystemWatcher watcher = new FileSystemWatcher(filePath);

                watcher.Created += FileSystemEventHandler;

                watcher.Changed += FileSystemEventHandler;

                watcher.Deleted += FileSystemEventHandler;

                watcher.EnableRaisingEvents = true;

            }

     

            private void FileSystemEventHandler(object sender, FileSystemEventArgs e)

            {

                if(e.ChangeType == WatcherChangeTypes.Changed)

                    Console.WriteLine("Changed~~~~~~~~~~~~~");

                else if (e.ChangeType == WatcherChangeTypes.Created)

                    Console.WriteLine("Created~~~~~~~~~~~~~");

                else if (e.ChangeType == WatcherChangeTypes.Deleted)

                    Console.WriteLine("Deleted~~~~~~~~~~~~~");

            }

    总结:通过文件的变更,可以通知我们进行相应的处理,例如重新加载dll文件到Appdomain当中,而无需重启应用程序(此演示示例将在下文档中进行体现)。

     

    2.      CodeDomProvider

    定义:CodeDomProvider 可用于创建和检索代码生成器和代码编译器的实例。代码生成器可用于以特定的语言生成代码,而代码编译器可用于将代码编译为程序集。

    A.      我们可以通过已经编写的固定代码来编译成固定的dll文件:

    具体实现:

                IDictionary<string, string> version = new Dictionary<string, string>();

                if (System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion().StartsWith("v4.0"))

                    version.Add("CompilerVersion", "v4.0");

                else

                    version.Add("CompilerVersion", "v3.5");

                CodeDomProvider provider = new CSharpCodeProvider(version);

                CompilerParameters parameters = new CompilerParameters();

                parameters.GenerateInMemory = false;

                parameters.OutputAssembly = assemblyFileName;

                parameters.ReferencedAssemblies.Add("System.dll");

                parameters.ReferencedAssemblies.Add("MyInterface.dll");

                CompilerResults clr = provider.CompileAssemblyFromSource(parameters, code);

                if (clr.Errors.HasErrors)

                {

                    throw new Exception(code + clr.Errors);

                }

    B.      我们也可以通过CodeDOM 模型生成和编译源代码

    具体实现:

        class CodeDomExample

        {

            // Build a Hello World program graph using

            // System.CodeDom types.

            public static CodeCompileUnit BuildHelloWorldGraph()

            {

                // Create a new CodeCompileUnit to contain

                // the program graph.

                CodeCompileUnit compileUnit = new CodeCompileUnit();

     

                // Declare a new namespace called Samples.

                CodeNamespace samples = new CodeNamespace("Samples");

                // Add the new namespace to the compile unit.

                compileUnit.Namespaces.Add(samples);

     

                // Add the new namespace import for the System namespace.

                samples.Imports.Add(new CodeNamespaceImport("System"));

     

                // Declare a new type called Class1.

                CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");

                // Add the new type to the namespace type collection.

                samples.Types.Add(class1);

     

                // Declare a new code entry point method.

                CodeEntryPointMethod start = new CodeEntryPointMethod();

     

                // Create a type reference for the System.Console class.

                CodeTypeReferenceExpression csSystemConsoleType = new CodeTypeReferenceExpression("System.Console");

     

                // Build a Console.WriteLine statement.

                CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(

                    csSystemConsoleType, "WriteLine",

                    new CodePrimitiveExpression("Hello World!"));

     

                // Add the WriteLine call to the statement collection.

                start.Statements.Add(cs1);

     

                // Build another Console.WriteLine statement.

                CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression(

                    csSystemConsoleType, "WriteLine",

                    new CodePrimitiveExpression("Press the Enter key to continue."));

     

                // Add the WriteLine call to the statement collection.

                start.Statements.Add(cs2);

     

                // Build a call to System.Console.ReadLine.

                CodeMethodInvokeExpression csReadLine = new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

     

                // Add the ReadLine statement.

                start.Statements.Add(csReadLine);

     

                // Add the code entry point method to

                // the Members collection of the type.

                class1.Members.Add(start);

     

                return compileUnit;

            }

     

            public static void GenerateCode(CodeDomProvider provider, CodeCompileUnit compileunit)

            {

                // Build the source file name with the appropriate

                // language extension.

                String sourceFile;

                if (provider.FileExtension[0] == '.')

                {

                    sourceFile = "TestGraph" + provider.FileExtension;

                }

                else

                {

                    sourceFile = "TestGraph." + provider.FileExtension;

                }

     

                // Create an IndentedTextWriter, constructed with

                // a StreamWriter to the source file.

                IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter(sourceFile, false), "    ");

                // Generate source code using the code generator.

                provider.GenerateCodeFromCompileUnit(compileunit, tw, new CodeGeneratorOptions());

                // Close the output file.

                tw.Close();

            }

     

            public static CompilerResults CompileCode(CodeDomProvider provider, String sourceFile, String exeFile)

            {

                // Configure a CompilerParameters that links System.dll

                // and produces the specified executable file.

                String[] referenceAssemblies = { "System.dll" };

                CompilerParameters cp = new CompilerParameters(referenceAssemblies, exeFile, false);

                // Generate an executable rather than a DLL file.

                cp.GenerateExecutable = true;

     

                // Invoke compilation.

                CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceFile);

                // Return the results of compilation.

                return cr;

            }

        }

           总结:通过CodeDomProvider这种方式,我们可以动态的编译一些dll,并通过Appdomain加载这些dll文件来实现我们需要的服务,可以说这种实现方式的灵活性更高。更有利于我们动态的部署,其中ESB就采用这种方式来实现服务的插入。后续我们将介绍一下Appdomain

     

    3.      Appdomain

    定义:Appdomain提供应用程序卸载,隔离,安全边界,一个Appdomain可以被创建多个,可以在Appdomain当中加载相应的dll文件。如果Appdomain变的不可控的时候,我们可以卸载相应的Appdomain而不影响主进程。多个应用程序可以运行在一个进程当中,多个线程也可以同时属于一个应用程序域,但是在给定的时间一个线程只能在一个应用程序域中运行。

    具体实现:

          AppDomainSetup appDomainSetup;

          appDomainSetup = new AppDomainSetup();

          appDomainSetup.LoaderOptimization = LoaderOptimization.SingleDomain;

          appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

          appDomainSetup.ShadowCopyDirectories = appDomainSetup.ApplicationBase;

          appDomainSetup.ShadowCopyFiles = "false";

          AppDomain appDomain = AppDomain.CreateDomain(assemblyFileName, null, appDomainSetup);

    总结:Appdomain可以加载相应的dll文件,这样我们可以创建多个Appdomain并将这些Appdomain当做相应的服务,Appdomain之间的加载、卸载之间不相互影响。Appdomain提供良好的应用程序的隔离,ESB当中即使用这种方式将服务之间隔离开来。

     

    4.      .net Remoting

    定义:.net Remoting一种分布式系统的处理方式,我们不打算研究它分布式的内容,.net Remoting还有一种应用场景就是实现应用程序域之间的访问,我们可以跨一个应用程序域与另外的应用程序域进行通信,及穿越边界值。

    具体实现:

    RemoteLoader remoteLoader = (RemoteLoader) appDomain.CreateInstance("Demo", "Demo.RemoteLoader").Unwrap();

     

    class RemoteLoader : MarshalByRefObject

        {

            public object Create(string assemblyFile, string typeName, object[] constructArgs)

            {

                 

                  // 略,详见示例代码

                return Activator.CreateInstance(matchType);

            }

        }

    总结:通过Appdomain.net Remoting的结合我们可以在某个Appdomain当中加载相应的dll并进行调取。使用.net Remoting核心是需要“调取类”或者是“处理类”必须继承自MarshalByRefObject

     

    代码如下:

    源代码下载地址

    资料如下:

    http://msdn.microsoft.com/zh-cn/library/system.io.filesystemwatcher.aspx

    http://msdn.microsoft.com/zh-cn/library/system.codedom.compiler.codedomprovider(VS.80).aspx

    http://msdn.microsoft.com/zh-cn/library/system.appdomain(v=VS.80).aspx

    http://msdn.microsoft.com/zh-cn/library/system.marshalbyrefobject(v=vs.80).aspx



    http://www.cnblogs.com/assessment/archive/2011/08/22/2138538.html

  • 相关阅读:
    tomcat最大线程数的设置(转)
    webService接口大全
    实用工具网站汇总
    Linux常用指令(待补充)
    svn的使用总结(待补充)
    养生
    nodejs知识结构
    NVM node版本管理工具的安装和使用
    MongoDB安装和MongoChef可视化管理工具的使用
    JavaScript模块化编程(三)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2152808.html
Copyright © 2011-2022 走看看