从数量到代码——通过代码生成机制落到实处强类型编制程序[下篇]

在《原理篇》中,大家谈到WCF自定义授权体系具有八个着力的机件:AuthorizationPolicy和ServiceAuthorizationManager,已经它们是什么撰写最后提供一种基于评释的授权达成。为了让自定义授权有深入的知情,我们来实行二个归纳实例来演示怎么样通过自定义这多个零部件达成“非剧中人物授权策略”。[源代码从这里下载]

《上篇》中,大家落到实处了将保留有新闻条目标XML向CodeDOM的更换,就是将XML文件生成三个CodeCompileUnit对象,而该CodeCompileUnit对象反映出来的DOM层次和我们将会扭转的代码文件向匹配。在下篇中,大家将落到实处整个代码生成系统的第3个步骤——透过VS的Custom
Tool实现数据(保存音讯条目的XML)向代码文件的自动转换

目录:
一 、创立示范程序化解方案
二、自定义AuthorizationPolicy
三、自定义ServiceAuthorizationManager
四 、应用自定义AuthorizationPolicy和ServiceAuthorizationManager

一、让MessageCodeGenerator继承BaseCodeGeneratorWithSite

《上篇》小编们创造了MessageCodeGenerator类,定义了之类三个BuildCodeObject方法完结将多少个XmlDocument转换到叁个CodeCompileUnit对象。

   1: namespace Artech.CodeDomGenerator

   2: {

   3:     public class MessageCodeGenerator

   4:     {     

   5:          // Others...

   6:         public CodeCompileUnit BuildCodeObject(XmlDocument messages);

   7:     }

   8: }

至今我们须要做的是让这一个MessageCodeGenerator继承二个越发的类:BaseCodeGeneratorWithSiteBaseCodeGeneratorWithSite所在的次第集名称为Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll,那是二个Visual
Studio SDK的先后集。大家例子选用的是Visual Studio
二零零六,你能够在如下的目录中找到该程序集:%ProgramFiles%Microsoft
Visual Studio 2010
SDK\VisualStudioIntegration\Common\Assemblies\v4.0
。假诺你从未设置VS
二零零六SDK,你能够从这里下载。

而外助长对Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll程序集的引用外,你还亟需添加八个附加的程序集引用:Microsoft.VisualStudio.OLE.Interop.dllMicrosoft.VisualStudio.Shell.Interop.dll,它们所在的目录分别是%ProgramFiles%Microsoft
Visual Studio 2010
SDK\VisualStudioIntegration\Common\Assemblies\v4.0
%ProgramFiles%Microsoft
Visual Studio 2010
SDK\VisualStudioIntegration\Common\Assemblies\v2.0

添加了相应的次第集引用,并将BaseCodeGeneratorWithSite本条抽象类作为MessageCodeGenerator的基类后,供给完结如下七个抽象方法:GenerateCodeGetDefaultExtension

   1: namespace Artech.CodeDomGenerator

   2: {   

   3:     public class MessageCodeGenerator : BaseCodeGeneratorWithSite

   4:     {      

   5:         public CodeCompileUnit BuildCodeObject(XmlDocument messages)

   6:         {

   7:             //......

   8:         }              

   9:         protected override byte[] GenerateCode(string inputFileName, string inputFileContent)

  10:         {

  11:            var messageDoc = new XmlDocument();

  12:             messageDoc.LoadXml(inputFileContent);

  13:             var codeObject = BuildCodeObject(messageDoc);

  14:             CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

  15:             CodeGeneratorOptions options = new CodeGeneratorOptions();

  16:             options.BracingStyle = "C";

  17:             using (StringWriter writer = new StringWriter())

  18:             {               

  19:                 provider.GenerateCodeFromCompileUnit(codeObject, writer, options);

  20:                 string code = writer.ToString();

  21:                 byte[] preambleBytes = Encoding.Unicode.GetPreamble();

  22:                 byte[] codeBytes = Encoding.Unicode.GetBytes(code);

  23:                 byte[] result = new byte[preambleBytes.Length + codeBytes.Length];

  24:                 Buffer.BlockCopy(preambleBytes, 0, result, 0, preambleBytes.Length);

  25:                 Buffer.BlockCopy(codeBytes, 0, result, preambleBytes.Length, codeBytes.Length);

  26:                 return result; 

  27:             }

  28:         }

  29:  

  30:         public override string GetDefaultExtension()

  31:         {

  32:             return ".cs";

  33:         }

  34:     }

  35: }

GenerateCode重回的字节数组表示最后生成的的代码的始末,在那边的逻辑很粗大略,正是经过CodeDomProviderCodeCompileUnit转折成基于具体编程语言(在那里大家只考虑C#)的代码。而GetDefaultExtension重回生成的代码文件的扩大名,在此处自然是“.cs”。

壹 、成立示范程序化解方案

。我们以此实例照旧接纳简易的盘算服务的事例,并且应用如下图所示的化解方案结构。可是,为了持续的授权策略要求,大家在劳动契约ICalculator接口上定义如下多个分别表示加、减、乘、除的八个运算操作。当然服务类型CalculatorService也开展对应的校订。

起名 1

ICalculator:

   1: using System.ServiceModel;

   2: namespace Artech.WcfServices.Contracts

   3: {

   4:     [ServiceContract(Namespace = "http://www.artech.com/")]

   5:     public interface ICalculator

   6:     {

   7:         [OperationContract(Action = "http://www.artech.com/calculator/add")]

   8:         double Add(double x, double y);

   9:         [OperationContract(Action = "http://www.artech.com/calculator/subtract")]

  10:         double Subtract(double x, double y);

  11:         [OperationContract(Action = "http://www.artech.com/calculator/multiply")]

  12:         double Multiply(double x, double y);

  13:         [OperationContract(Action = "http://www.artech.com/calculator/divide")]

  14:         double Divide(double x, double y);

  15:     }

  16: }

CalculatorService:

   1: using Artech.WcfServices.Contracts;

   2: namespace Artech.WcfServices.Services

   3: {

   4:     public class CalculatorService : ICalculator

   5:     {

   6:         public double Add(double x, double y)

   7:         {           

   8:             return x + y;

   9:         }

  10:         public double Subtract(double x, double y)

  11:         {

  12:             return x - y;

  13:         }

  14:         public double Multiply(double x, double y)

  15:         {

  16:             return x * y;

  17:         }

  18:         public double Divide(double x, double y)

  19:         {

  20:             return x / y;

  21:         }

  22:     }

  23: } 

后天我们的授权策略是这样的:操作Add和Subtract针对仅对用户Foo开放,而Multiply和Divide操作仅对用户Bar开放。纵然那个不难的授权完全能够由此在对应的劳动操作方法上利用PrincipalPermissionAttribute并点名Name属性来落实。可是我们要尝试通过自定义AuthorizationPolicy和ServiceAuthorizationManager来达成如此的授权策略。先来探视自定义的AuthorizationPolicy的定义。

二、将MessageCodeGenerator注册成COM组件

到当前大家MessageCodeGenerator完全通过托管程序编写制定,可是VS和增添是经过COM的措施开始展览互动的,所以大家须要将MessageCodeGenerator注册成COM组件。大家先是须求做的是对MessageCodeGenerator所在的程序集举行登记。一般地,实行登记的顺序集都具有二个强名称,所以我们先对先后集举办签订契约。这只必要对定义MessageCodeGenerator所在的类型的“签名”选项实行如下设置就足以了。

起名 2我们还亟需对先后集的COM可知性实行相应的安装。对于COM可知性的安装,大家只需在AssemblyInfo.cs文件中,添加如下一个ComVisibleAttribute天性并将参数设置成true即可(私下认可为false)。

   1: // Setting ComVisible to false makes the types in this assembly not visible 

   2: // to COM components.  If you need to access a type in this assembly from 

   3: // COM, set the ComVisible attribute to true on that type.

   4: [assembly: ComVisible(true)]

二、自定义AuthorizationPolicy

小编们将自定义的AuthorizationPolicy创设在Hosting项目中。由于IAuthorizationPolicy定义在System.IdentityModel程序集中,大家先为Hosting项目添加该程序集的引用。由于授权策略相比简单,大家向来上自定义的AuthorizationPolicy命名为SimpleAuthorizationPolicy,下边是成套SimpleAuthorizationPolicy的定义。

   1: using System;

   2: using System.Collections.Generic;

   3: using System.IdentityModel.Claims;

   4: using System.IdentityModel.Policy;

   5: using System.Linq;

   6: namespace Artech.WcfServices.Hosting

   7: {

   8:     public class SimpleAuthorizationPolicy : IAuthorizationPolicy

   9:     {

  10:         private const string ActionOfAdd = "http://www.artech.com/calculator/add";

  11:         private const string ActionOfSubtract = "http://www.artech.com/calculator/subtract";

  12:         private const string ActionOfMultiply = "http://www.artech.com/calculator/multiply";

  13:         private const string ActionOfDivide = "http://www.artech.com/calculator/divide";

  14:  

  15:         internal const string ClaimType4AllowedOperation = "http://www.artech.com/allowed";

  16:  

  17:         public SimpleAuthorizationPolicy()

  18:         {

  19:             this.Id = Guid.NewGuid().ToString();

  20:         }

  21:         public bool Evaluate(EvaluationContext evaluationContext, ref object state)

  22:         {

  23:             if (null == state)

  24:             {

  25:                 state = false;

  26:             }

  27:             bool hasAddedClaims = (bool)state;

  28:             if (hasAddedClaims)

  29:             {

  30:                 return true; ;

  31:             }

  32:             IList<Claim> claims = new List<Claim>();

  33:             foreach (ClaimSet claimSet in evaluationContext.ClaimSets)

  34:             {

  35:                 foreach (Claim claim in claimSet.FindClaims(ClaimTypes.Name, Rights.PossessProperty))

  36:                 {

  37:                     string userName = (string)claim.Resource;

  38:                     if (userName.Contains('\\'))

  39:                     {

  40:                         userName = userName.Split('\\')[1];

  41:                         if (string.Compare("Foo", userName, true) == 0)

  42:                         {

  43:                             claims.Add(new Claim(ClaimType4AllowedOperation,ActionOfAdd, Rights.PossessProperty));

  44:                             claims.Add(new Claim(ClaimType4AllowedOperation, ActionOfSubtract, Rights.PossessProperty));

  45:                         }

  46:                         if (string.Compare("Bar", userName, true) == 0)

  47:                         {

  48:                             claims.Add(new Claim(ClaimType4AllowedOperation,ActionOfMultiply, Rights.PossessProperty));

  49:                             claims.Add(new Claim(ClaimType4AllowedOperation, ActionOfDivide, Rights.PossessProperty));

  50:                         }

  51:                     }

  52:                 }

  53:             }

  54:             evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, claims));

  55:             state = true;

  56:             return true;           

  57:         }

  58:         public ClaimSet Issuer

  59:         {

  60:             get { return ClaimSet.System; }

  61:         }

  62:         public string Id { get; private set; }

  63:     }

  64: }

大家最首要来介绍伊娃luate方法中,该办法首要的逻辑是如此的:通过伊娃luationContext现有的注明集获取当前的用户名(注脚类型和申明权限分别为ClaimTypes.Name和Rights.PossessProperty)。针对拿到出来的用户名,创造于被授权服务操作关联的注解。在那之中注解的三要素(类型、权限和财富)分别为:“http://www.artech.com/allowed”、Rights.PossessProperty和操作的Action。最后将这些声明组成一个声明集添加到EvaluationContext中。

为了让大家定义的MessageCodeGenerator通过COM组件的款式暴流露来,我们需求功过在器类型上通过使用三个GuidAttribute内定1个唯一标识。那个唯一标识可以通过VS自带的GUID生成器生成。

   1: [Guid("F9A0FCB3-864F-4B87-885B-FAEBC860BD64")]

   2: public class MessageCodeGenerator : BaseCodeGeneratorWithSite

   3: {  

   4:     //Others...

   5: }

程序集的挂号通过命令行工具RegAsm.exe达成,大家只须求运维通过VS
二〇〇九的命名行工具,执行RegAsm.exe命令对编写翻译生成的先后集进行注册。

   1: RegAsm "c:\CodeDOMGenerator\Artech.CodeDomGenerator.CodeGenerator.dll"

实际上,大家也得以间接通过VS对相应的体系举办相应的装置,让VS在编写翻译实现后自行达成对指标程序基的登记。你只要求在类型安装对话框中的Build页,钩选“Register
for COM interop
”即可。

起名 3

注:由于我们的MessageCodeGenerator内部引用到了另三个程序集Microsoft.VisualStudio.Shell.Interop.dll中的有个别品种,你需求经过执行如下RegAsm.exe命令行对该程序基举办注册,并运用/tlb开关生成类型库。

   1: RegAsm /tlb "%ProgramFiles%Microsoft Visual Studio 2010 SDK\VisualStudioIntegration\Common\Assemblies\v2.0\Microsoft.VisualStudio.Shell.Interop.dll"

叁 、设置注册表

到如今停止,大家定义的代码生成器MessageCodeGenerator已经由此COM组件的样式暴透露来了,大家需求作的就是让VS能够健康地加载该COM组件,这通过安装VS相关的注册表消息来形成。VS二〇一〇与代码生成相关的登记表项定义在HKLM\Software\Microsoft\VisualStudio\10.0\Generators\节点下。该节点下的子节点(Key)均经过相应的GUID表示,分化的GUID实际上意味着的是相应的编制程序语言。当中{164B10B9-B200-11D0-8C61-00A0C91E29D5}代表VB.NET,而C#对应的GUID为下图选中的{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}

起名 4
现在我们要求在代表C#的节点下创办3个Key,并起名为MessageCodeGenerator,即大家约定的代码生成器的名称。

起名 5 

如上海体育场面所示,大家必要对咱们添加的登记表键实行如下三项设置:

  • (Default)[REG_SZ]:起名,安装代码生成器的表述性音讯;
  • CLSID[REG_SZ]:用作COM组件的代码生成器的GUID,即大家在概念MessageCodeGenerator类新通过GuidAttribute特性内定的GUID,注意不要忘了花括号;
  • GeneratesDesignTimeSource[REG_WWORD]:
    0还是1,注解是还是不是提供规划时原代码生成的帮助

三、自定义ServiceAuthorizationManager

当授权相关的扬言集通过自定义的AuthorizationPolicy被初叶化之后,大家透过自定义ServiceAuthorizationManager来分析这么些评释,并作做出当前操作是还是不是被授权调用的尾声判定。类似于SimpleAuthorizationPolicy,大家将自定义的ServiceAuthorizationManager起名为SimpleServiceAuthorizationManager,同样定义于Hosting项目中,上面是全部SimpleServiceAuthorizationManager类型的定义。

   1: using System.IdentityModel.Claims;

   2: using System.Security.Principal;

   3: using System.ServiceModel;

   4: namespace Artech.WcfServices.Hosting

   5: {

   6:     public class SimpleServiceAuthorizationManager : ServiceAuthorizationManager

   7:     {

   8:         protected override bool CheckAccessCore(OperationContext operationContext)

   9:         {

  10:             string action = operationContext.RequestContext.RequestMessage.Headers.Action;

  11:             foreach (ClaimSet claimSet in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)

  12:             {

  13:                 if (claimSet.Issuer == ClaimSet.System)

  14:                 {

  15:                     foreach (Claim c in claimSet.FindClaims(SimpleAuthorizationPolicy.ClaimType4AllowedOperation, Rights.PossessProperty))

  16:                     {

  17:                         if (action == c.Resource.ToString())

  18:                         {

  19:                             GenericIdentity identity = new GenericIdentity("");

  20:                             operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] =

  21:                                 new GenericPrincipal(identity, null);

  22:                             return true;

  23:                         }

  24:                     }

  25:                 }

  26:             }

  27:             return false;            

  28:         }

  29:     }

  30: }

出于基于被授权操作的宣示已经通过SimpleAuthorizationPolicy被成功添加到伊娃luationContext的扬言集列表,并最终作为当下AuthorizationContext评释集的一局部。那么,即使在这个代表被授权操作的宣示中,具有多个是根据当前被调用的服务操作的评释,就表示当前的劳务操作调用被授权了的。那样的逻辑达成在重写的CheckAccessCore方法中。其它,还有一些内需专注的是:在做出成功授权的情景下,要求安装当前的安全核心,因为无论这些安全重点是不是必要,WCF总是会计算从当前AuthorizationContext的本性列表中去获取该安全核心。借使没有,会抛出相当。

肆 、通过Custom Tool直接通过XML生成C#代码

于今大家就能够来一直利用大家大家的MessageCodeGenerator了。未来大家创立三个品种,添加3个用以保存新闻的XML文件,比如起名为Messages.xml,内容如下:

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <messages>

   3:   <message id="MandatoryField" value="The {0} is mandatory."  category="Validation"/>

   4:   <message id="GreaterThan" value="The {0} must be greater than {1}."  category="Validation"/>

   5:   <message id="ReallyDelete" value="Do you really want to delete the {0}."  category="Confirmation"/>

   6: </messages>

接下来右击该XML文件,在弹出的上下文菜单中选取Properties选项。你会意识在性质对话框中有个叫作Custom
Tool
的属性名称,在该项上填写上大家的代码生成器的名目:MessageCodeGenerator。

起名 6
此后,当您右击该XML文件时,在上下文菜单中都会多出1个称为Run Custom
Tool
的门类,选拔它大家的.cs文件将会自动生成,

起名 7

该.cs文件和我们在《上篇》给出的代码一模一样。那么大家就足以信赖生成出来的代码,以一种强类型的办法获取相应的、被格式化的音讯文本

   1: //------------------------------------------------------------------------------

   2: // <auto-generated>

   3: //     This code was generated by a tool.

   4: //     Runtime Version:4.0.30319.1

   5: //

   6: //     Changes to this file may cause incorrect behavior and will be lost if

   7: //     the code is regenerated.

   8: // </auto-generated>

   9: //------------------------------------------------------------------------------

  10:  

  11: namespace Artech.CodeDomGenerator

  12: {

  13:     

  14:     

  15:     public class Messages

  16:     {

  17:         

  18:         public class Validation

  19:         {

  20:             

  21:             public static Artech.CodeDomGenerator.MessageEntry MandatoryField = new Artech.CodeDomGenerator.MessageEntry("MandatoryField", "The {0} is mandatory.", "Validation");

  22:             

  23:             public static Artech.CodeDomGenerator.MessageEntry GreaterThan = new Artech.CodeDomGenerator.MessageEntry("GreaterThan", "The {0} must be greater than {1}.", "Validation");

  24:         }

  25:         

  26:         public class Confirmation

  27:         {

  28:             

  29:             public static Artech.CodeDomGenerator.MessageEntry ReallyDelete = new Artech.CodeDomGenerator.MessageEntry("ReallyDelete", "Do you really want to delete the {0}.", "Confirmation");

  30:         }

  31:     }

  32: }

四 、应用自定义AuthorizationPolicy和ServiceAuthorizationManager

到近来甘休,八个着力的自定义对象(SimpleAuthorizationPolicy和SimpleServiceAuthorizationManager)都早就成立好了,大家将来通过布置的方法将它们设置到应用到服务的ServiceAuthorizationBehavior服务作为上。上面两段XML片断分别表示服务寄宿和客户端的安插。

劳务寄宿配置:

   1: <?xml version="1.0"?>

   2: <configuration>

   3:   <system.serviceModel>

   4:     <services>

   5:       <service name="Artech.WcfServices.Services.CalculatorService" behaviorConfiguration="useCustomAuthorization">

   6:         <endpoint address="http://127.0.0.1/calculatorservice"  binding="ws2007HttpBinding"                         contract="Artech.WcfServices.Contracts.ICalculator"/>

   7:       </service>

   8:     </services>

   9:     <behaviors>

  10:       <serviceBehaviors>

  11:         <behavior  name="useCustomAuthorization">         

  12:           <serviceAuthorization principalPermissionMode="Custom"                    serviceAuthorizationManagerType="Artech.WcfServices.Hosting.SimpleServiceAuthorizationManager,Artech.WcfServices.Hosting">

  13:             <authorizationPolicies >

  14:               <add policyType="Artech.WcfServices.Hosting.SimpleAuthorizationPolicy, Artech.WcfServices.Hosting" />

  15:             </authorizationPolicies>

  16:           </serviceAuthorization>

  17:           <serviceDebug includeExceptionDetailInFaults="true"/>

  18:         </behavior>

  19:       </serviceBehaviors>

  20:     </behaviors>

  21:   </system.serviceModel>

  22: </configuration>

客户端配置:

   1: <?xml version="1.0"?>

   2: <configuration>

   3:   <system.serviceModel>

   4:     <client>

   5:       <endpoint name="calculatorService" address="http://127.0.0.1/calculatorservice" binding="ws2007HttpBinding"                       contract="Artech.WcfServices.Contracts.ICalculator"/>

   6:     </client>  

   7:   </system.serviceModel>

   8: </configuration>

咱俩最后要求证明的WCF是不是能够根据大家自定义的策略实行授权。为了演示方便,小编创制了如下八个称号为Invoke的推抢方法。Invoke方法的八个参数分别代表举行劳动调用的委托、服务代办对象和操作名称。服务操作调用会在该办法中施行,并最终输出相应的文字表示服务调用是还是不是中标。

   1: static void Invoke(Action<ICalculator> action, ICalculator proxy, string operation)

   2: {

   3:     try

   4:     {

   5:         action(proxy);

   6:         Console.WriteLine("服务操作\"{0}\"调用成功...", operation);

   7:     }

   8:     catch (Exception ex)

   9:     {

  10:         Console.WriteLine("服务操作\"{0}\"调用失败...", operation);

  11:     }

  12: }

在如下的代码中,大家独家以用户名Foo和Bar的名义通过上边的Invoke扶助方法对计量服务的多少个操作举办走访。而程序执行的尾声结果是和大家自定义的授权策略是一致的:用户Foo仅仅授予了调用Add和Substract操作的权力,而其余三个授权给用户Bar。

   1: static void Main(string[] args)

   2: {

   3:     ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorService");

   4:     NetworkCredential credential = channelFactory.Credentials.Windows.ClientCredential;

   5:     credential.UserName = "Foo";

   6:     credential.Password = "Password";

   7:     ICalculator calculator = channelFactory.CreateChannel();

   8:     Invoke(proxy => proxy.Add(1, 2), calculator, "Add");

   9:     Invoke(proxy => proxy.Subtract(1, 2), calculator, "Subtract");

  10:     Invoke(proxy => proxy.Multiply(1, 2), calculator, "Multiply");

  11:     Invoke(proxy => proxy.Divide(1, 2), calculator, "Divide");

  12:     Console.WriteLine();

  13:  

  14:     channelFactory = new ChannelFactory<ICalculator>("calculatorService");

  15:     credential = channelFactory.Credentials.Windows.ClientCredential;

  16:     credential.UserName = "Bar";

  17:     credential.Password = "Password";

  18:     calculator = channelFactory.CreateChannel();

  19:     Invoke(proxy => proxy.Add(1, 2), calculator, "Add");

  20:     Invoke(proxy => proxy.Subtract(1, 2), calculator, "Subtract");

  21:     Invoke(proxy => proxy.Multiply(1, 2), calculator, "Multiply");

  22:     Invoke(proxy => proxy.Divide(1, 2), calculator, "Divide");

  23:  

  24:     Console.Read();

  25: }

出口结果:

   1: 服务操作"Add"调用成功...

   2: 服务操作"Subtract"调用成功...

   3: 服务操作"Multiply"调用失败...

   4: 服务操作"Divide"调用失败...

   5:  

   6: 服务操作"Add"调用失败...

   7: 服务操作"Subtract"调用失败...

   8: 服务操作"Multiply"调用成功...

   9: 服务操作"Divide"调用成功...

[WCF权限控制]WCF自定义授权体系详解[原理篇]
[WCF权限控制]WCF自定义授权种类详解[实例篇]

伍 、将MessageCodeGenerator和文书扩展名绑定

实际我们能够看出VS代码生成机制的本质:将多个文本作为源文件(Source),利用相应的生成器生成靶子文件(Destination)。关于选择什么样的生成器,则是因而源文件的Custom
Tool
天性进行匹配的。除了那种必要手工业安装文件属性的法子展开源文件和生成器之间的11分关系外,还具备另一种特别便利的合作格局:基于源文件扩充名的匹配

现今大家的音讯文件时通过二个XML文件(文件的结构和扩大名均是XML),假使大家明日给它一种特别的扩张名,并且将设置源文件扩展名和代码生成器的合作关系,就无需再手工业地为源文件设置Custom
Tool
这一性质了

实质上,大家得以二个粗略的注册表设置就能够完成那样的法力。如若作为MessageCodeGenerator的源文件的扩张名为msg(不要以为是OutLook邮件音信),我们住必要在地方提到过的依据某种编制程序语言的登记表节点下,创造1个以扩大名命名的Key,并将Default值直接设置成代码生成器的称谓即可。起名 8

以后当您添加八个增添名为.msg的文件后,Custom
Tool自动为你设置成MessageCodeGenerator。无需手工业安装,你就足以一向通过Run
Custom Tool
变更对应的代码文件了。

起名 9

 

从数额到代码——通过代码生成机制落实强类型编制程序[上篇]
从数额到代码——通过代码生成机制完结强类型编制程序[下篇]
从数额到代码——基于T4的代码生成形式
成立代码生成器能够很简短:怎样通过T4模板生成代码?[上篇]
开创代码生成器能够非常粗大略:怎么样通过T4模板生成代码?[下篇] 

 

作者:Artech
出处:http://artech.cnblogs.com/
正文版权归小编和微博共有,欢迎转发,但未经作者同意必须保留此段注解,且在篇章页面显明地点给出原来的文章连接,不然保留追究法律权利的义务。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图