You don't need a global bool as such. I started doing this in my own library but haven't really worked on the OOP side yet, or tidied up my in process memory reading. Or really used it... Anyway, use object oriented programming, I hear it's great :-P.
What I've done is I have an abstract Memory class that has all the method signatures I need such as Read<T> or ReadBytes or whatever I want (and Write etc etc). I then have two subclasses one for in process and one for out of process. The in process can implement the methods using Marshal.Read, or native pointers, and the out of process using ReadProcessMemory. You can then use a static factory pattern to get the appropriate reader (I don't do this, I have it all encapsulated in a different class - more later). I.e.
Code:
abstract class Memory {
....
public static Memory CreateForPID(int pid) {
if (pid == Process.GetCurrentProcess().ID) // we're in process
{
return new InProcessMemory(pid);
} else {
return new OutProcessMemory(pid);
}
}
As for the 'hidden' part of your question: In my work, I have a class I've called ExtendedProcess that provides all my extended functionality for a Process (memory reading/writing, injection etc). This internally manages all the sub classes such as Memory and Injector and determines whether they are appropriate for the situation, or what kind is appropriate. I.e. I have a Memory property that returns a Memory reader. If the ExtendedProcess object is for the current process, it returns an internal reader, otherwise an out of process reader.
In terms of what is injected and what isn't, that often seems to be a matter of preference. I remember Apoc saying at one stage that everything for Onyx was injected (I think, but I may be wrong). This of course makes some things a bit more difficult (like debugging - but logging comes in handy there). I believe I remember another member, amadmonk, once saying that he had injected parts that communicated with an external process to facilitate communication between multiple bots. Effectively it comes down to there being more than one way to skin a cat. Try to work out what you want to achieve from your bot and whether those features will be easier internal or external. If you're injecting already, it's another headache to set up communication between processes, so you need to be sure that your reasons for doing that are worthwhile.
That said, if you design your modules with future extensibility in mind then it is often easier to add features later without drastic rewrites. Just be careful not to make it harder to design features for right now at the expense of possibly wanting to do something in the future.