I'm redesigning one of my programs which performs certain actions on processes of interest (known as Monitored Processes in my program). Some actions I always need to do on those processes are:Open process handleGet process nameClose process handleAnd some further actions I may need to do on some or all of them are:Suspend process Resume process Set process priority Set process affinityPreviously I simply had a handler class that opened a handle to the process, checked its name, and performed the requested actions. All of that is done via p/invoke, I don't use .NET's Process class at all.However I am trying to redesign it from a SOLID perspective, so I created a MonitoredProcess object and have added a number of methods to it to perform the actions.Here it is in its current state:public class MonitoredProcess : IMonitoredProcess{    private readonly IMonitoredProcessConfig config;    private readonly int processId;    private IntPtr handle = IntPtr.Zero;    private uint suspendResumeResult;    private string processName;    public IMonitoredProcessConfig Config { get { return config; } }    public int ProcessId { get { return processId; } }    public uint SuspendResumeResult { get { return suspendResumeResult; } }    public string ProcessName    {        get        {            if (processName == null) PopulateProcessName();            return processName;        }    }    public MonitoredProcess(IMonitoredProcessConfig config, int processId)    {        if (config == null) throw new ArgumentNullException(config);        this.config = config;        this.processId = processId;    }    public bool OpenProcess()    {        var alreadyOpen = handle != IntPtr.Zero;        if (alreadyOpen) return true;        handle = Kernel32.OpenProcess(config.RequiredRights, false, (uint)processId);        return handle != IntPtr.Zero;    }    public bool CloseProcess()    {        var closed = Kernel32.CloseHandle(handle);        if (closed) handle = IntPtr.Zero;        return closed;    }    public uint Resume()    {        suspendResumeResult = Ntdll.NtResumeProcess(handle);        return suspendResumeResult;    }    public uint Suspend()    {        suspendResumeResult = Ntdll.NtSuspendProcess(handle);        return suspendResumeResult;    }    private void PopulateProcessName()    {        var buffer = new StringBuilder((int)Kernel32.GeneralConstants.MAX_PATH);        var success = 0 != Psapi.GetModuleFileNameEx(            handle,            IntPtr.Zero,            buffer,            (uint)buffer.Capacity            );        processName = success ? Path.GetFileName(buffer.ToString()) : string.Empty;    }}I haven't yet added methods to set the process's priority and affinity. The interface it implements is not yet really defined, it will become whatever the class eventually exposes.Question:Is this class doing too much? Should a process know how to suspend/resume itself, and set its own priority and CPU affinity? Or should I have other classes that take an IMonitoredProcess and perform these actions on them (which is how I did it before)?In the way I did it before, the classes performing the actions implemented them through p/invoke, so they knew they could throw and catch Win32Exceptions to get the error message. If this MonitoredProcess class implements everything via p/invoke internally, the class calling those methods technically shouldn't know how they're implemented, so has no reason to either throw or catch Win32Exceptions. And I wouldn't want to simply throw them from this class (even wrapped in a domain-specific exception) because in half the places I call the methods I'm not interested in the outcome, but I'd still have to try/catch it every time - and it creates objects unnecessarily.Which again makes me wonder if this class should really be doing all these actions, ostensibly on itself, but it uses external functions to perform all of them.
Single Responsibility - is this class doing too much?
c#;design;single responsibility
I would call the class ProcessController rather then MonitoredProcess. The class instance is not a process, it encapsulates a process handle. And it does not just monitor, it controls.You could pass the process id to the constructor.This would get your terminology straight, it would be clear your class controls a process for you. Which is one responsibility. So you're good.