How can I automatically generate a constructor that receives and stores services for free?

杀马特。学长 韩版系。学妹 提交于 2019-12-24 16:26:31

问题


Problem

I regularly find myself manually typing out code that looks like this:

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

    public SomeClass(ServiceA serviceA, ServiceB serviceB)
    {
        this.serviceA = serviceA.;
        this.serviceB = serviceB;
    }
}

Requirements

I would like to save time by having a way to generate as much of this as possible. I don't want to use a tool that requires a purchase. The only information that is variable here is the class name and the types of the services. So in this example, I would like to be to type something minimal like this:

  1. Some+Shortcut
  2. SomeClass
  3. ServiceA
  4. ServiceB
  5. Enter

I'm also open to a solution that still requires me to type in the names of the fields. I don't mind whether or not the private access modifier is present in the field definitions, although I prefer to not have it since the code is a bit leaner that way. Similarly, I'm willing to accept a solution that doesn't generate read-only fields, but I do prefer them since I seldom want to change a service after my class is initialised.

What I've Tried

The quickest solution I know of at the moment is to type something like the following in another section of code and tell Visual Studio to create the class and constructor from its usage.

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

However, I don't always work in this order; sometimes I want to create a class before using it. So what I typically do is this:

  1. Invoke the ctor code snippet.
  2. Fill in the constructor body.
  3. Use CodeRush Xpress to generate the fields. (It provides a way to generate read-only fields, whereas Visual Studio doesn't make them read-only.)

Code-snippets work well, but I don't think they support variable numbers of parameters, so they're probably not suited to this problem.


回答1:


Go to your default C# code snippets location, usually in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Visual C# and make a copy of ctor.snippet into your personal code snippets location, rename it, and give it a proper name and shortcut key. Then change the declaration (look at other existing ones), something like the below can do the job. Once you create it, you can simply type svc + TAB (or whatever shortcut you choose then tab) in an empty class file, and you should get the content filled up, alternatively you may be able to customize a class template so when you do add new, you can select your new template.

<?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>

In the above we declare variables for the classes svcA = ServiceA, svcB = ServiceB, and the class variables svcAvar = serviceA and svcBvar = serviceB, so we can easily modify in one location, you can create more for the params in the constructor, etc, but should be enough to get you started.

Regarding the variable number of params, you can use the default params literal which would then let you type whatever params you need after you insert the ctor, if you have varying class level variables, then just like others have said, create several snippets with different shortcuts, like svc, svc1, svc2, svc3 etc

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

then ...<![CDATA[$accessor$ $classname$ (...$params$)



来源:https://stackoverflow.com/questions/20154790/how-can-i-automatically-generate-a-constructor-that-receives-and-stores-services

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!