title: Register, Resolve, Release pattern usage
body: <p>I'm currently reading the book <a href="https://rads.stackoverflow.com/amzn/click/com/1935182501" rel="nofollow noreferrer" rel="nofollow noreferrer">Dependency Injection in .NET</a> by Mark Seeman. In this book he recommends the <em>Register, Resolve, Release</em> pattern and also recommends that each of these operations should appear only once in your application's code.</p>
  
  <p>My situation is the following: I'm creating an application that communicates with a PLC (a kind of industrial embedded computer) using a proprietary communication protocol for which the PLC manufacturer provides an library. The library's documentation recommends creating a connection to the PLC and maintaining it open; then using a timer or a while loop, a request should be periodically sent to read the contents of the PLC's memory, which changes over time. </p>
  
  <p>The values read from the PLC's memory should be used to operate on a database, for which I intend to use Entity Framework. As I understand it, the best option is to create a new <code>dbContext</code> on every execution of the loop in order to avoid a stall cache or concurrency problems (the loop could be potentially executing every few milliseconds for a long time while the connection is kept open all the time). </p>
  
  <p>My first option was calling Resolve on application construction to create a long-lived object that would be injected with the PLC communication object and would handle loop execution and keep the connection alive. Then, at the beginning of every loop execution I intended to call Resolve again to create a short-lived object that would be injected with a new <code>dbContext</code> and which would perform the operations on the database. However, after reading the advice on that book I'm doubting whether I'm on the right track. </p>
  
  <p>My first idea was to pass a delegate to the long-lived object upon its construction that would allow it to build new instances of the short-lived object (I believe it is the factory pattern), thus removing the dependency on the DI container from my long-lived object. However, this construct still violates the aforementioned pattern. </p>
  
  <p>Which is the right way of handling Dependency Injection in this situation?</p>
  
  <p>My first attempt without DI:</p>
  
  <pre><code>class NaiveAttempt
  {
      private PlcCommunicationObject plcCommunicationObject;
      private Timer repeatedExecutionTimer;
  
      public NaiveAttempt()
      {
          plcCommunicationObject = new PlcCommunicationObject("192.168.0.10");
          plcCommunicationObject.Connect();
  
          repeatedExecutionTimer = new Timer(100); //Read values from PLC every 100ms
          repeatedExecutionTimer.Elapsed += (_, __) =&gt;
          {
              var memoryContents = plcCommunicationObject.ReadMemoryContents();
              using (var ctx = new DbContext())
              {
                  // Operate upon database
                  ctx.SaveChanges();
              }
          }
      }
  }
  </code></pre>
  
  <p>Second attempt using Poor man's DI.</p>
  
  <pre><code>class OneLoopObject
  {
      private PlcCommunicationObject plcCommunicationObject;
      private Func&lt;DbContext&gt; dbContextFactory;
  
      public OneLoopObject(PlcCommunicationObject plcCommunicationObject, DbContext dbContext
      {
          this.plcCommunicationObject = plcCommunicationObject;
          this.dbContext = dbContext;
      }
  
      public void Execute()
      {
          var memoryContents = plcCommunicationObject.ReadMemoryContents();
          // Operate upon database    
      }
  }
  
  class LongLivedObject
  {
      private PlcCommunicationObject plcCommunicationObject;
      private Timer repeatedExecutionTimer;   
      private Func&lt;OneLoopObject&gt; oneLoopObjectFactory;
  
      public LongLivedObject(PlcCommunicationObject plcCommunicationObject, Func&lt;PlcCommunicationObject, OneLoopObject&gt; oneLoopObjectFactory)
      {
          this.plcCommunicationObject = plcCommunicationObject;
          this.dbContextFactory = dbContextFactory;
          this repeatedExecutionTimer = new Timer(100);
          this.repeatedExecutionTimer.Elapsed += (_, __) =&gt;
          {
              var loopObject = oneLoopObjectFactory(plcCommunicationObject);
              loopObject.Execute();
          }
      }
  }
  
  static class Program
  {
      static void Main()
      {
          Func&lt;PlcCommunicationObject, OneLoopObject&gt; oneLoopObjectFactory = plc =&gt; new OneLoopObject(plc, new DbContext());
          var myObject = LongLivedObject(new PlcCommunicationObject("192.168.1.1"),  oneLoopObjectFactory)
  
          Console.ReadLine();
      }
  }
  </code></pre>