Register, Resolve, Release pattern usage

ploeh service locator
composition root ploeh
dependency injection anti pattern
pure di
captured dependency
ioc container
service locator vs di
di ioc

I'm currently reading the book Dependency Injection in .NET by Mark Seeman. In this book he recommends the Register, Resolve, Release pattern and also recommends that each of these operations should appear only once in your application's code.

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.

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 dbContext 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).

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 dbContext 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.

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.

Which is the right way of handling Dependency Injection in this situation?

My first attempt without DI:

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 += (_, __) =>
        {
            var memoryContents = plcCommunicationObject.ReadMemoryContents();
            using (var ctx = new DbContext())
            {
                // Operate upon database
                ctx.SaveChanges();
            }
        }
    }
}

Second attempt using Poor man's DI.

class OneLoopObject
{
    private PlcCommunicationObject plcCommunicationObject;
    private Func<DbContext> 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<OneLoopObject> oneLoopObjectFactory;

    public LongLivedObject(PlcCommunicationObject plcCommunicationObject, Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory)
    {
        this.plcCommunicationObject = plcCommunicationObject;
        this.dbContextFactory = dbContextFactory;
        this repeatedExecutionTimer = new Timer(100);
        this.repeatedExecutionTimer.Elapsed += (_, __) =>
        {
            var loopObject = oneLoopObjectFactory(plcCommunicationObject);
            loopObject.Execute();
        }
    }
}

static class Program
{
    static void Main()
    {
        Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory = plc => new OneLoopObject(plc, new DbContext());
        var myObject = LongLivedObject(new PlcCommunicationObject("192.168.1.1"),  oneLoopObjectFactory)

        Console.ReadLine();
    }
}

The first edition states (chapter 3, page 82):

In its pure form, the Register Resolve Release pattern states that you should only make a single method call in each phase [...] an application should only contain a single call to the Resolve method.

This description stems from the idea that your application only contains either one root object (typically when writing a simple console application), or one single logical group of root types, e.g. MVC controllers. With MVC controllers, for instance, you would have a custom Controller Factory, which is provided by the MVC framework with a controller type to build. That factory will, in that case, only have a single call to Resolve while supplying the type.

There are cases, however, where your application has multiple groups of root types. For instance, a web application could have a mix of API Controllers, MVC Controllers and View Components. For each logical group you would likely have a single call to Resolve, and thus multiple calls to Resolve (typically because each root type gets its own factory) in your application.

There are other valid reasons for calling back into the container. For instance, you might want to defer building part of the object graph, to combat the issue of Captive Dependencies. This seems your case. Another reason for having an extra resolve is when you use the Mediator pattern to dispatch messages to a certain implementation (or implementations) that can handle that message. In that case your Mediator implementation would typically wrap the container and call Resolve. The Mediator’s abstraction would likely be defined in your Domain library, while the Mediator’s implementation, with its knowledge of the container, should be defined inside the Composition Root.

The advice of having a single call to Resolve should, therefore, not be taken literally. The actual goal here is to build a single object graph as much as possible in one call, compared to letting classes themselves call back into the container to resolve their dependencies (i.e. the Service Locator anti-pattern).

The other important point that (the second edition of) the book makes is

Querying for Dependencies, even if through a DI Container, becomes a Service Locator if used incorrectly. When application code (as opposed to infrastructure code) actively queries a service in order to be provided with required Dependencies, then it has become a Service Locator.

A DI Container encapsulated in a Composition Root isn't a Service Locator—it's an infrastructure component.

(note: this quote is from the second edition; Although the first edition contains this information as well, it might be formulated differently).

So the goal of the RRR pattern is to promote encapsulation of the DI Container within the Composition Root, which is why it insists in having a single call to Resolve.

Do note that while writing the second edition, Mark and I wanted to rewrite the discussion of the RRR pattern. Main reason for this was that we found the text to be confusing (as your question indicates). However, we eventually ran out of time so we decided to simply remove that elaborate discussion. We felt that the most important points were already made.

Register, Resolve, Release pattern usage, The first edition states (chapter 3, page 82):. In its pure form, the Register Resolve Release pattern states that you should only make a single  The Register Resolve Release pattern. The subject of Dependency Injection (DI) in general, and DI Containers specifically, suffers from horrible terminology that seems to confuse a lot of people. Newcomers to DI often think about DI Containers as a sort of Abstract Factory on steroids.

Combining factories with DI is a common solution. There is absolutely nothing wrong with creating and disposing objects dynamically in your program (it's much more difficult and limiting to try to account for every bit of memory you'll need up front).

I found a post by Mark Seeman about the Register, Resolve, Release Pattern (RRR) here: http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/

He states that...

The names originate with Castle Windsor terminology, where we:

Register components with the container

Resolve root components

Release components from the container

So the RRR pattern is limited to the DI Container. You do indeed Register and Release components with the container one time in your application. This says nothing about objects not injected through DI, ie those objects created dynamically in the normal execution of your program.

I have seen various articles use distinct terminology for the two different types of things you create in your program with relation to DI. There are Service Objects, ie those global objects injected via DI to your application. Then there are Data or Value Objects. These are created by your program dynamically as needed and are generally limited to some local scope. Both are perfectly valid.

Chapter 3. DI Containers, COMPOSITION ROOT; REGISTER RESOLVE RELEASE; A DI CONTAINER can make the use of DI more efficient, but an application must first and Seom DI CONTAINERS ecfs nsdarndeut rxb EROPERTY JNJECTION pattern, qgr ffc lk  Of course, it is an acronym that stands for: Register – Resolve – Release. The first step, when using any DI Container, is registration of the object. In this step, we define which object of which class or interface will be created once dependency is encountered.

It sounds like you want to be able to both resolve objects from the container and then release them, all without directly referencing the container.

You can do that by having both a Create and a Release method in your factory interface.

public interface IFooFactory
{
   Foo Create();
   void Release(Foo created);
}

This allows you to hide references to the container within the implementation of IFooFactory.

You can create your own factory implementation, but for convenience some containers, like Windsor, will create the factory implementation for you.

var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<Foo>());
container.Register(
    Component.For<IFooFactory>()
        .AsFactory()
);

You can inject the factory, call Create to obtain an instance of whatever the factory creates, and when you're done with it, pass that instance to the Release method.

Windsor does this by convention. The method names don't matter. If you call a method of the interface that returns something, it attempts to resolve it. If a method returns void and takes an argument then it tries to release the argument from the container.

Behind the scenes it's roughly the same as if you wrote this:

public class WindsorFooFactory : IFooFactory
{
    private readonly IWindsorContainer _container;

    public WindsorFooFactory(IWindsorContainer container)
    {
        _container = container;
    }

    public Foo Create()
    {
        return _container.Resolve<Foo>();
    }

    public void Release(Foo created)
    {
        _container.Release(created);
    }
}

The factory implementation "knows" about the container, but that's okay. Its job is to create objects. The factory interface doesn't mention the container, so classes that depend on the interface aren't coupled to the container. You could create an entirely different implementation of the factory that doesn't use a container. If the object didn't need to be released you could have a Release method that does nothing.

So, in a nutshell, the factory interface is what enables you to follow the resolve/release part of the pattern without directly depending on the container.

Here's another example that shows a little bit more of what you can do with these abstract factories.

Design Decisions, Agile Coding with Design Patterns and Solid Principles Gary McLean Hall phases of the Register, Resolve, Release pattern. public class IocConfiguration { private than it otherwise might be if it was contained in the application entry point. A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container. Using a DI Container is often a good choice. In that case it should be applied using the Register Resolve Release pattern entirely from within the Composition Root.

Autofac uses Func<> as the factory pattern so you could always do the same:

public class Foo()
{
  private readonly Func<Bar> _barFactory;

  public Foo(Func<Bar> barFactory)
  {
    _barFactory = barFactory;
  }
}

Adding Factory Interfaces for factories is not something I think anyone should need to do most of the time, it's extra work for little to no reward.

Then you simply need to keep track of which entities are externally owned or DI owned for your release (Dispose in C#).

Adaptive Code Via C#: Agile Coding with Design Patterns and Solid , When you register things in Autofac, you might have registrations that look like as their interface types and as themselves, then resolve them in the lambda:. Resolve < IService > (); Assert. IsTrue (container. Kernel. ReleasePolicy. HasTrack (service)); The tracking will propagate onto the parent service so again if we don’t release the service after using it, we will get a memory leak! Always release after you are done Container. Register (Component. For < IDisposableComponent > (). ImplementedBy < MyDisposableComponent > ().

How do I pick a service implementation by context?, Wikipedia says: "Dependency injection is a software design pattern in which The registration of dependencies are separated from the creation and use of It is constructor-injected with IIocResolver and uses it to resolve and release objects. Wikipedia says: "Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object (or client) and are made part of the client's state. The pattern separates the creation of a client's dependencies from its own behavior, which allows program designs to

Dependency Injection, Dependency injection and the use of IoC containers is becoming more and talk about the static or singleton container and why this 'pattern' is such a bad idea. You register all your components with the container and then resolve the root  When you resolve services inside the constructor, they are released when the service is released. So, you don’t care about releasing/disposing services resolved inside the constructor (just like

How not to do dependency injection, The Problem. When you use Dependency Inversion Principle then the class get its This follows the Register Resolve Release (RRR) pattern. IoC Container (a.k.a. DI Container) is a framework for implementing automatic dependency injection. It manages object creation and it's life-time, and also injects dependencies to the class. The IoC container creates an object of the specified class and also injects all the dependency objects through a constructor, a property or a method at run

Comments
  • I think that the problem that I'm facing and I don't know how to solve is as simple as that: I have two Service Objects, one that must be long-lived and another one that must be short-lived. My intention was to use the DI container to create both, but that would mean two Resolve calls. How is this best achieved?
  • Inject a factory for the short-lived object
  • Mark Seeman has written a bunch of articles about Windsor, and it's a popular container, but for some reason it's not one of the containers he talks about in his book. He mentions Autofac, which does something similar with delegate factories, and it depends on the scope to ensure that what is resolved gets released.
  • As a matter of fact, Castle Windsor is discussed thoroughly in the first edition. In the second edition, however, we decided to remove the discussion of Castle Windsor (and other containers).
  • @Steven I only have the first edition. I did not realize that the second audition had two co-authors. My future references will cite the authors correctly. Thank you!