C# 如何自动生成免费接收和存储服务的构造函数? 问题

C# 如何自动生成免费接收和存储服务的构造函数? 问题,c#,visual-studio,visual-studio-2012,code-generation,constructor-injection,C#,Visual Studio,Visual Studio 2012,Code Generation,Constructor Injection,我经常发现自己手动键入如下代码: public class SomeClass { readonly ServiceA serviceA; readonly ServiceB serviceB; public SomeClass(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA.; this.serviceB = serviceB; } }

我经常发现自己手动键入如下代码:

public class SomeClass
{
    readonly ServiceA serviceA;
    readonly ServiceB serviceB;

    public SomeClass(ServiceA serviceA, ServiceB serviceB)
    {
        this.serviceA = serviceA.;
        this.serviceB = serviceB;
    }
}
要求 我想通过有一种方法尽可能多地生成这些内容来节省时间。我不想使用需要购买的工具。这里唯一可变的信息是类名和服务的类型。在这个例子中,我想输入一些最小值,如下所示:

public class SomeClass
{
    readonly ServiceA serviceA;
    readonly ServiceB serviceB;

    public SomeClass(ServiceA serviceA, ServiceB serviceB)
    {
        this.serviceA = serviceA.;
        this.serviceB = serviceB;
    }
}
  • 一些+捷径
  • SomeClass
  • ServiceA
  • ServiceB
  • 进入
  • 我也愿意接受一个仍然需要我输入字段名称的解决方案。我不介意字段定义中是否存在
    private
    access修饰符,尽管我不喜欢使用它,因为这样代码更精简。类似地,我愿意接受一个不生成只读字段的解决方案,但我更喜欢它们,因为我很少想在初始化类后更改服务

    我试过的 目前我知道的最快的解决方案是在另一段代码中键入如下内容,并告诉VisualStudio根据其用法创建类和构造函数

    new SomeClass((ServiceA)null, (ServiceB)null);
    
    然而,我并不总是按照这个顺序工作;有时我想在使用它之前创建一个类。所以我通常做的是:

  • 调用
    ctor
    代码段
  • 填写构造函数主体
  • 使用CodeRush Xpress生成字段。(它提供了一种生成只读字段的方法,而VisualStudio不将其设置为只读。)
  • 代码段工作得很好,但我认为它们不支持可变数量的参数,因此它们可能不适合这个问题。

    转到默认的C代码段位置,通常在C:\Program Files(x86)中\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Visual C#并将ctor.snippet复制到您的个人代码段位置,重命名它,并为其指定正确的名称和快捷键。然后更改声明(看看其他现有的声明),类似下面这样的操作可以完成这项工作。创建后,您只需在一个空类文件中键入
    svc+TAB
    (或您选择的任何快捷方式,然后是TAB),您就可以填充内容,或者您可以自定义一个类模板,以便在添加新模板时,您可以选择新模板

    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
        <CodeSnippet Format="1.0.0">
            <Header>
                <Title>Some Constructor</Title>
                <Shortcut>svc</Shortcut>
                <Description>my description</Description>
                <Author>Jason was here</Author>
                <SnippetTypes>
                    <SnippetType>Expansion</SnippetType>
                </SnippetTypes>
            </Header>
            <Snippet>
                <Declarations>
                    <Literal>
                        <ID>accessor</ID>
                        <ToolTip>Access modifier</ToolTip>
                        <Default>public</Default>
                    </Literal>
                    <Literal Editable="false">
                        <ID>classname</ID>
                        <ToolTip>Class name</ToolTip>
                        <Function>ClassName()</Function>
                        <Default>ClassNamePlaceholder</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcA</ID>
                        <ToolTip>Service A</ToolTip>
                        <Default>ServiceA</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcAvar</ID>
                        <ToolTip>Service A</ToolTip>
                        <Default>serviceA</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcB</ID>
                        <ToolTip>Service B</ToolTip>
                        <Default>ServiceB</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcBvar</ID>
                        <ToolTip>Service B</ToolTip>
                        <Default>serviceB</Default>
                    </Literal>
                </Declarations>
                <Code Language="csharp"><![CDATA[readonly $svcA$ $svcAvar$;
        readonly $svcB$ $svcBvar$;
    
        $accessor$ $classname$ ($svcA$ serviceA, $svcB$ serviceB)
        {
            this.$svcAvar$ = serviceA;
            this.$svcBvar$ = serviceB
        }$end$]]>
                </Code>
            </Snippet>
        </CodeSnippet>
    </CodeSnippets>
    
    然后转到默认的C代码段位置,通常在C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\snippets\1033\Visual C中,将ctor.snippet复制到您的个人代码段位置,重命名它,并给它一个正确的名称和快捷键。然后更改声明(看看其他现有的声明),类似下面这样的操作可以完成这项工作。创建后,您只需在一个空类文件中键入
    svc+TAB
    (或您选择的任何快捷方式,然后是TAB),您就可以填充内容,或者您可以自定义一个类模板,以便在添加新模板时,您可以选择新模板

    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
        <CodeSnippet Format="1.0.0">
            <Header>
                <Title>Some Constructor</Title>
                <Shortcut>svc</Shortcut>
                <Description>my description</Description>
                <Author>Jason was here</Author>
                <SnippetTypes>
                    <SnippetType>Expansion</SnippetType>
                </SnippetTypes>
            </Header>
            <Snippet>
                <Declarations>
                    <Literal>
                        <ID>accessor</ID>
                        <ToolTip>Access modifier</ToolTip>
                        <Default>public</Default>
                    </Literal>
                    <Literal Editable="false">
                        <ID>classname</ID>
                        <ToolTip>Class name</ToolTip>
                        <Function>ClassName()</Function>
                        <Default>ClassNamePlaceholder</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcA</ID>
                        <ToolTip>Service A</ToolTip>
                        <Default>ServiceA</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcAvar</ID>
                        <ToolTip>Service A</ToolTip>
                        <Default>serviceA</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcB</ID>
                        <ToolTip>Service B</ToolTip>
                        <Default>ServiceB</Default>
                    </Literal>
                    <Literal Editable="true">
                        <ID>svcBvar</ID>
                        <ToolTip>Service B</ToolTip>
                        <Default>serviceB</Default>
                    </Literal>
                </Declarations>
                <Code Language="csharp"><![CDATA[readonly $svcA$ $svcAvar$;
        readonly $svcB$ $svcBvar$;
    
        $accessor$ $classname$ ($svcA$ serviceA, $svcB$ serviceB)
        {
            this.$svcAvar$ = serviceA;
            this.$svcBvar$ = serviceB
        }$end$]]>
                </Code>
            </Snippet>
        </CodeSnippet>
    </CodeSnippets>
    

    然后是

    代码片段,但有一个适用于1-N构造函数的版本。称它们为
    class1
    class2
    ,等等。如果您的所有代码都遵循类似的模式,您可以轻松创建一个简单的应用程序,根据一些输入名称输出文件。也可以作为visual studio模板(如xml、html、c#class等)免费版本的CodeRush来执行此操作。@TGH,您建议使用哪种工作流?是否使用外部程序为此程序提供全局键盘快捷键?我更喜欢与IDE集成的产品。@N4TKD,它的哪些功能提供了此功能?除了我在问题中提到的代码片段之外,我找不到一个有帮助的,但是有一个1-N构造函数的版本。称它们为
    class1
    class2
    ,等等。如果您的所有代码都遵循类似的模式,您可以轻松创建一个简单的应用程序,根据一些输入名称输出文件。也可以作为visual studio模板(如xml、html、c#class等)免费版本的CodeRush来执行此操作。@TGH,您建议使用哪种工作流?是否使用外部程序为此程序提供全局键盘快捷键?我更喜欢与IDE集成的产品。@N4TKD,它的哪些功能提供了此功能?除了我在问题中提到的那一个,我找不到有帮助的。