Kiquenet
Kiquenet

Reputation: 14996

Initialize Custom Object Lists in Powershell

I have the following code in C# .NET 3.5 - VS2010, for initializing a custom object list

I need do the same too in a Powershell 2.0 script.

Any suggestions about it, without use Add-Type?

public static List<ReplaceForDeployFile> CreateReplaceList()
{
    var list = new List<ReplaceForDeployFile>()
    {
        new ReplaceForDeployFile()
        { 
            PathFile = "web.config",
            ReplaceList = 
                new List<ItemReplaceForDeployFile>()
                {
                    new ItemReplaceForDeployFile()
                    {
                        ReplaceType = "System.String", 
                        ValueSource = @"value=""Value1""", 
                        ValueForDES = @"value=""Value2""",
                    },
                    new ItemReplaceForDeployFile()
                    {
                        ReplaceType = "System.String", 
                        ValueSource = @"customErrors mode=""On""", 
                        ValueForDES = @"customErrors mode=""Off""",
                    },
               },
          },            
    };
    return list;
}

Upvotes: 1

Views: 1477

Answers (2)

Amith George
Amith George

Reputation: 5916

I am aware the OP had a restriction of PS v2. However Google leads us to this question even if we search for how to do this in v3. I am adding this answer to help other v3 users who might be looking for this info.

The convenience of Object Initializers can be achieved in PowerShell using the following syntax,

$item = [FullyQualifiedClassName]@{Prop1='Value1'; Prop2='Value2'}

The OP's example

var item = new ItemReplaceForDeployFile() { ReplaceType = "System.String", ValueSource = @"value=""Value1""", ValueForDES = @"value=""Value2""" };

becomes

$item = [Namespace.SubNs.ItemReplaceForDeployFile]@{ReplaceType='System.String'; ValueSource='value="Value1"'; ValueForDES='value="Value2"'}

Source: http://blogs.msdn.com/b/powershell/archive/2012/06/14/new-v3-language-features.aspx

New Conversions

Sometimes you want the keys of a hash literal to be ordered. You can now cast to [ordered] and we create an OrderedDictionary instead of HashTable. This only works with literals – if you try it on a variable, the ordering is no longer available.

[ordered]@{a=1; b=2}

In a similar manner, you can create custom objects with a simple cast:

[pscustomobject]@{x=1; y=2}

This does not create a HashTable; it creates a PSObject with note properties. If you are casting a literal, the note properties are added in the order they appear in the literal. If you are casting anything else, the ordering is determined by the IDictionary iterator.

If a type has a default constructor and settable properties, you can also use a hash table to case an object to that type:

[System.Drawing.Point]@{X=1; Y=2}

This will call the default constructor and set the properties named in the hash table.

Upvotes: 3

Richard
Richard

Reputation: 108995

The answer to your question rather depends on how and where type ItemReplaceForDeployFile is defined. Once loaded and it only has a default constructor then you'll need to assign the properties separately:

$x = new-object CorrectNamespace.ItemReplaceForDeployFile;
$x.ReplaceType = 'System.String';
$x.ValueSource = 'customErrors mode="On"', 
$x.ValueForDES = 'customErrors mode="Off"',

To load the assembly without using Add-Type use [Assembly]::LoadFrom($path) or [Assembly]::LoadWithPartialName($name).

But

Add-Type -AssemblyName name

is far easier and clearer.

However, if you want PowerShell to dynamically compile source in C# (or VB using the -CodeDomProvider parameter to override the C# default) into a temporary assembly and load that assembly you'll need to do a lot of work (working with the applicable CodeDOM types yourself). Add-Type is vastly easier.

It would help to know why you want to avoid Add-Type.

Upvotes: 2

Related Questions