0

I like to separate business logic out of POCOs into controllers.

If an object must be thread safe, where do I put the lock code? In the POCO itself? Or in a controller?

Might make sense because value types cannot be locked?

I.e., the controller:

namespace Project1.Controllers
{
    public class LogManagerController
    {
        private object _lock = new object();

        public LogManager Fill(TimeSpan interval, DateTime? lastLog)
        {
            return new LogManager {Interval = interval, LastLog = lastLog};
        }

        public void Update(LogManager logManager, DateTime lastLog)
        {
            lock (_lock)
            {
                logManager.LastLog = lastLog;
            }
        }

        public DateTime? Get(LogManager logManager)
        {
            lock (_lock)
            {
                return logManager.LastLog;
            }
        }
    }
}

The model:

namespace Project2.Models
{
    public class LogManager
    {
        public TimeSpan Interval { get; set; }
        public DateTime? LastLog { get; set; }
    }
}
Hoppe
  • 101
  • 5
  • If you put business logic into controller, what will you do if your business logic is needed by a non web based application? I am assuming you are talking about controllers in a web MVC framework. – CodingYoshi Oct 05 '18 at 00:10
  • 1
    If LogManager has an actual need to be thread-safe, then it's probably not really a POCO. Offloading the thread-safety to another class is risky, because any future use case where another component of your application needs a LogManager will either require the programmer to remember to use LogManagerController, or they'll end up re-implementing the locking. – RuslanD Oct 05 '18 at 02:14
  • Hmm, then I wonder if this class should be places in a models namespace or elsewhere @RuslanD – Hoppe Oct 05 '18 at 13:04

1 Answers1

1

The only reason I can see where you might run into thread safety here is due to Interval and LastLog needing to be kept in sync. If that's the case, then avoid the problem altogether by making that class immutable:

namespace Project2.Models
{
    public class LogManager
    {
        public LogManager(TimeSpan interval, DateTime? lastLog)
            => (Interval, LastLog) = (interval, lastLog);

        public TimeSpan Interval { get; }
        public DateTime? LastLog { get; }
    }
}

Then, when the values change, create a new instance of LogManager, rather than mutating an existing value.

But having said that, there's nothing abut your code that suggests this is the case. You update LastLog but leave Interval alone. So it's unclear why you feel this class might not be thread safe already.

David Arno
  • 38,972
  • 9
  • 88
  • 121
  • I am more concerned as to where in my application I should put the locking code. In the POCO or in a controller? – Hoppe Oct 05 '18 at 13:03
  • 3
    @Hoppe as your question stands, it’s unclear why you are considering locking it the first place. – David Arno Oct 05 '18 at 14:05