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

时间:2013-11-22 21:27:14

标签: 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;
    }
}

要求

我想通过尽可能多地生成这个来节省时间。我不想使用需要购买的工具。这里唯一可变的信息是类名和服务类型。所以在这个例子中,我想要输入这样的最小值:

  1. 部分 + 快捷方式
  2. SomeClass
  3. ServiceA
  4. ServiceB
  5. 输入
  6. 我也对一个仍需要我输入字段名称的解决方案持开放态度。我不介意private访问修饰符是否存在于字段定义中,尽管我更喜欢不使用它,因为代码有点精简。同样,我愿意接受一个不生成只读字段的解决方案,但我更喜欢它们,因为我很少想在初始化类之后更改服务。

    我尝试过什么

    目前我所知道的最快的解决方案是在另一部分代码中键入类似下面的内容,并告诉Visual Studio根据其用法创建类和构造函数。

    new SomeClass((ServiceA)null, (ServiceB)null);
    

    但是,我并不总是按此顺序工作;有时我想在使用之前创建一个类。所以我通常做的是:

    1. 调用ctor代码段。
    2. 填写构造函数体。
    3. 使用CodeRush Xpress生成字段。 (它提供了一种生成只读字段的方法,而Visual Studio不会将它们设置为只读。)
    4. 代码片段效果很好,但我认为它们不支持可变数量的参数,所以它们可能不适合这个问题。

1 个答案:

答案 0 :(得分:4)

转到默认的C#代码段位置,通常位于 C:\ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC#\ Snippets \ 1033 \ Visual C#中,并复制<将em> ctor.snippet 放入您的个人代码段位置,重命名,并为其指定正确的名称和快捷键。然后更改声明(查看其他现有的声明),类似下面的内容可以完成工作。创建它之后,您只需在空类文件中键入svc + 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>

在上面我们为类svcA = ServiceAsvcB = ServiceB以及类变量svcAvar = serviceAsvcBvar = serviceB声明了变量,因此我们可以在一个位置轻松修改,可以为构造函数中的params创建更多,但应该足以让你开始。

关于params的变量数,你可以使用默认的params文字,然后你可以在插入ctor后输入你需要的任何参数,如果你有不同的类级别变量,那么就像其他人说的那样,创建几个包含不同快捷方式的摘录,例如 svc svc1 svc2 svc3

<Literal>
    <ID>params</ID>
    <ToolTip>Parameter list</ToolTip>
    <Default></Default>
</Literal>

然后...<![CDATA[$accessor$ $classname$ (...$params$)