If ε-TeX extensions are available, then you can systematically nest \unexpanded inside \edef.
You can achieve the sequence
\definesomething{⟨MacroNamePart⟩}{⟨Code with #1⟩} → define \something@MacroNamePart
\something@MacroNamePart → define \something{#1} → Code with #1
as follows:
\makeatletter \newcommand\definesomething[2]{% \expandafter\edef\csname something@#1\endcsname{% \unexpanded{\def\something}####1\unexpanded{{#2}}% }% }% \show\definesomething \definesomething{whatever}{Code with #1}% \show\something@whatever \something@whatever \show\something \stop

Each definition-level where the hashes of the parameter of the user-level-macro shall be doubled (so that they can be halved during expansion of the macro) requires another nesting-level of \unexpanded.
As a rule of thumb the only things that must not go into \unexpanded are the hashes-and-digit-sequences that denote arguments that occur in the ⟨parameter texts⟩ of those macros that get defined via \edef.
The braces wherein the ⟨balanced texts⟩ of the ⟨definition texts⟩ of these \edef-definitions are nested also need not to go into \unexpanded which makes life easy.
You can easily achieve the sequence
\definesomething{⟨MacroNamePart⟩}{⟨Code with #1⟩} → define \something@DefinitionNestLevelOne
\something@DefinitionNestLevelOne → define \something@DefinitionNestLevelTwo
\something@DefinitionNestLevelTwo → define \something@MacroNamePart
\something@MacroNamePart → define \something{#1} → Code with #1
as follows:
\makeatletter \newcommand\definesomething[2]{% \edef\something@DefinitionNestLevelOne{%<-opening brace of \edef-definition-text needs not be in \unexpanded % here things are surrounded by 1 \edef, thus everything that is not a parameter % of this one \edef must be nested in 1 level of \unexpanded: \unexpanded{\edef\something@DefinitionNestLevelTwo}{%<-opening brace of \edef-definition-text needs not be in \unexpanded % here things are surrounded by 2 \edef, thus everything that is not a parameter % of one of these 2 \edef must be nested in 2 levels of \unexpanded: \unexpanded{\unexpanded{\expandafter\edef\csname something@#1\endcsname}}{%<-opening brace of \edef-definition-text needs not be in \unexpanded % here things are surrounded by 3 \edef, thus everything that is not a parameter % of one of these 3 \edef must be nested in 3 levels of \unexpanded: \unexpanded{\unexpanded{\unexpanded{\def\something}}}################1\unexpanded{\unexpanded{\unexpanded{{#2}}}}% }%<-closing brace of \edef-definition-text needs not be in \unexpanded }%<-closing brace of \edef-definition-text needs not be in \unexpanded }%<-closing brace of \edef-definition-text needs not be in \unexpanded }% \show\definesomething \definesomething{whatever}{Code with #1}% \show\something@DefinitionNestLevelOne \something@DefinitionNestLevelOne \show\something@DefinitionNestLevelTwo \something@DefinitionNestLevelTwo \show\something@whatever \something@whatever \show\something \stop

What can you do if ε-TeX-extensions are not available?
In the very special case that ⟨Code with #1⟩ does only contain #1 but not ##1 etc, you can use ⟨Code with #1⟩ for defining a macro which processes one argument, and for multiplying the hashes call that macro with multiple hashes as argument. Could look like this:
\makeatletter \newcommand\definesomething[2]{% {% \def\tempa##1{\def\tempa{#2}}% \tempa{########1}% \expandafter }\expandafter\innerdefinesomething\expandafter{\tempa}{#1}% }% \newcommand\innerdefinesomething[2]{% \@namedef{something@#2}{% % ... \def\something####1{#1}% % ... }} \show\definesomething \definesomething{whatever}{Code with #1}% \show\something@whatever \something@whatever \show\something \stop
\edef/\xdef-contexts. In\edef/\xdef-contexts both during\the-expansion of token-parameters/token-registers and during delivering the balanced text of\unexpandedhash-doubling takes place. This is for compensating that the amount of hashes will be halved when expanding the macro that was defined in terms of\edef/\xdef. Unexpanded-writing (also with\scantokens' pseudo-files) also doubles hashes. But reading the (pseudo)-file requires re-tokenization. Hereby catcode-régimes might cause problems.