Q:

How to define constants for use with With[] in one place and then apply them later?

I like to use With[] with constants that I need to use in 2 different places.
Instead of typing the same long list of constants in 2 places, I have been trying to figure how to use a variable for this list, and then use this variable in the few places I want to use the list.
The problem is that I need to Hold the list and then ReleaseHold it later when time to use it, but I can't get this part right. (tried many things, nothing working for me)
Here is an example:
With[{$age = 2, $salary = 3},
 x = $age
 ]

With[{$age = 2, $salary = 3},
 y = $age
 ]

I do not want to type the same constants around (in my case, these are very long), and I was trying to do something like this:
c = HoldForm[{$age = 2, $salary = 3}]

With[Release[c],
 x = $age
 ]

With[Release[c],
 y = $age
 ]

I tried many other combinations of the above. So many version of Hold* and Release*, I find them all very confusing.
question is: Any one knows how to do the above, so I can reused the list in more than one place without actually copy it?
To put this in context, here is an example where this would be needed:
I can't do surround everything with With in Manipulate: (and I can't put a With outside Manipulate for what I am doing, everything must be inside Manipulate)
Manipulate[

 Evaluate@With[{$age = 2, $salary = 3},
   x;
   $age,

   {{x, $age, "age="}, 0, 10, 1}
   ]

 ]

Not valid syntax. (due to the "," needed to separate the Manipulate expression from the controls). (it now thinks With has 3 arguments)
I could ofcourse do
Manipulate[

 With[{$age = 2, $salary = 3},
  x;
  $age
  ],

 Evaluate@With[{$age = 2, $salary = 3},
   {{x, $age, "age="}, 0, 10, 1}
   ]

 ]

But as you see, I had to copy the list of constants around. 
If I can figure how to define the list once, I can put it in the Initialization section on Manipulate and use it, like this:
Manipulate[

 With[ReleaseHold[myList],
  x;
  $age
  ],

 Evaluate@With[ReleaseHold[myList],
   {{x, $age, "age="}, 0, 10, 1}
   ],

 Initialization :>
  (
   myList = HoldAll[{$age = 2, $salary = 3}];
   )

 ]

I think what I want to do is possible, I just can't figure the correct commands to use for the Hold/Release hold part. 
edit (1)
I thought I put an example of why I want to use constants in With.
I came up with this new method :) to allow me to simulate a record or a  struct. 
The constant values will be the named field of the record (which is just a list really).
For field name, I give it a sequential number, (I start from 1) and I use $field=number, and then in the code, I write  struct[[$field]]=... to access the field.
I need to share the values of the named fields to the struct between the Manipulate expression and the control area, since both need to use the same struct. 
Here is a simple example below of a Manipulate that reads the age and current salary from the UI and the expression and assigns new salary based on current salary and ago.
The record is used to communicate the data between the control area and the expression and lower level functions.
In my current demo, I have hundreds of such parameters, (I actually have now few demos, all in one demo, and I flip between different UI layouts (controls) based on which choice is selected on the UI) and using records will simplify life for me, since now I can make function calls, and just pass few parameters, records that contain the UI parameters, and not 100's of the individual parameters, which is what I have to do now. As I said many times before, Mathematica needs a real record/struct as a basic data struct, in addition to List, and Array and such, which is integrated into M.
(the UI parameters have to be send, all, to lower level functions, and there is no other choice than doing this. I do not want to use global variables. Bad design).
I also can now pass this record by reference If I want to to allow updates to happen into it inside other much lower level functions. I am still evaluating this method to see if I can actually use it in my main code.
 (*verison 1.1*)
Manipulate[

 With[{$age = 1, $salary = 2, $newSalary = 3},

  updateRecord[record_] := Module[{},

    (*update/process UI input*)

    record[[$newSalary]] = record[[$salary]] + record[[$age]]*10;

    (*return result*)
    record
    ];

  (*call lower level function to process UI parameters*)
  myRecord = updateRecord[Unevaluated@myRecord];

  (*display the result *)
  Grid[{
    {"age=", myRecord[[$age]]},
    {"current salary=", myRecord[[$salary]]},
    {"new salary=", myRecord[[$newSalary]]}
    }]
  ],

 (* build the UI controls *)
 Evaluate@With[{$age = 1, $salary = 2, $newSalary = 3},
   Grid[{

     {"age=",
      Manipulator[Dynamic[age, {age = #; myRecord[[$age]] = age} &],
       {10, 100, 1}, ImageSize -> Tiny], Dynamic[age]},

     {"salary=",
      Manipulator[
       Dynamic[salary, {salary = #; myRecord[[$salary]] = salary} &],
       {10, 10000, 10}, ImageSize -> Tiny], Dynamic[salary]}

     }
    ]
   ],

 {{myRecord, {10, 100, 100}}, None},
 {{age, 10}, None},
 {{salary, 1000}, None},
 TrackedSymbols -> {age, salary}

 ]

edit(2)
On trying to use Leonid below, I can use it in the Manipulate expression, but can't figure how to use in the control area.
Here is the original example using With in 2 places:
Manipulate[

 With[{$age = 2, $salary = 3},
  x + $age
  ],

 Evaluate@With[
   {$age = 2, $salary = 3},
   {{x, $age, "age="}, 0, 10, 1}
   ],
 {x, None}
 ]

now using the new Leonid method below, this is what I have so far:
Manipulate[

 env[
  x + $age
  ],

 Evaluate@With[
   {$age = 2, $salary = 3},
   {{x, $age, "age="}, 0, 10, 1}
   ],
 {x, None},

 Initialization :>
  (
   ClearAll[makeCustomEnvironment];
   SetAttributes[makeCustomEnvironment, HoldAll]; 
   makeCustomEnvironment[values : (_Symbol = _) ..] := 
    Function[code, With @@ Hold[{values}, code], HoldAll];

   env = makeCustomEnvironment[$age = 2, $salary = 3];

   )
 ]

But is it possible to use it for the control also? I can't just do this:
Manipulate[

 env[
  x + $age
  ],

 env[
  {$age = 2, $salary = 3},
  {{x, $age, "age="}, 0, 10, 1}
  ],
 {x, None},

 Initialization :>
  (
   ClearAll[makeCustomEnvironment];
   SetAttributes[makeCustomEnvironment, HoldAll]; 
   makeCustomEnvironment[values : (_Symbol = _) ..] := 
    Function[code, With @@ Hold[{values}, code], HoldAll];

   env = makeCustomEnvironment[$age = 2, $salary = 3];

   )
 ]

as the above gives many errors. 
edit(3)
deleted as was incorrect
edit (4)
deleted content of edit(3) above as it included a user error on my side reporting an issue.
Here is the WRI support response to why I was getting the error 
Manipulate::vsform: Manipulate argument env[{{age,100,age},10,200,1}] does
not have the correct form for a variable specification. >>

When I was writing the following code:
Manipulate[
  env[
   record[[$age]] = age;
   record[[$salary]] = 60*age;
   {record[[$age]], record[[$salary]]}
   ],

 env[
    {{age, 100, "age"}, 10, 200, 1}
    ],

  {{record, {40, 5}}, None},
  {{salary, 40000}, None},
  TrackedSymbols :> {age},
  Initialization :>
   (
    makeCustomEnvironmentAlt =
     Function[Null, Function[code, With @@ Hold[{##}, code], HoldAll],
      HoldAll];
    env = makeCustomEnvironmentAlt[$age = 1, $salary = 2];
    )

  ]

This is the support explanation of why this error came showed up:
The issue is specifically with the section:

Evaluate@env[{{age, 100, "age"}, 10, 200, 1}]

Manipulate doesn't really evaluate until it gets to the Initialization
option, but it will check its input for correct form. Mathematica reads the
main body of the Manipulate before running the Initialization option. This
is can be verified by using a Print statement:

Initialization -> (Print["Test"]; 
  makeCustomEnvironmentAlt = 
   Function[Null, Function[code, With @@ Hold[{##}, code], HoldAll], 
    HoldAll];
  env = makeCustomEnvironmentAlt[$age = 1, $salary = 2]; 
  Print["Test"])

Test does not print. 

Getting around this will be probably not be clean.
....
Having  the code for the controller for age depend on evaluation of 
some function which must be initialized does not appear to be possible 
with simply Manipulate. 

I hope this information helps. And thanks for everyone's help and also for WRI support and explanation.

A:

What I'd do is to write a function generator to create custom (lexical) environments:
ClearAll[makeCustomEnvironment];
SetAttributes[makeCustomEnvironment, HoldAll];
makeCustomEnvironment[values : (_Symbol = _) ..] :=
   Function[code, With @@ Hold[{values}, code], HoldAll];

This takes a declaration list and creates a pure function which uses With internally with encapsulated constants. I used With@@Hold[...] to fool the renaming mechanism of Function so that it would not rename the variables inside With (instead of With, one could use the withRules function suggested by @Szabolcs, which would lead to a slightly different substitution semantics).
Now, we create our custom function:
env = makeCustomEnvironment[$age = 2, $salary = 3];

And use it like so:
In[25]:= 
env[x=$age];
x

Out[26]= 2

In[27]:= 
env[y=$age];
y

Out[28]= 2

The advantage of this construct with respect to a saved variable (with rules or whatever) is that here we encapsulate behavior rather than state. This is arguably cleaner and more along the functional programming paradigm (we create here a closure rather than instantiate a class). 
EDIT
Apparently, the rules for demonstrations are pretty strict, and won't allow the sugested code. This version will hopefully be ok:
makeCustomEnvironmentAlt = 
 Function[Null,
   Function[code, With @@ Hold[{##}, code], HoldAll],
   HoldAll]

But you'll have to remember the format of input arguments (which was clear for the initial solution due to the use of suggestive pattern).

