Search code examples
c#-4.0spring.netconstructor-injection

Spring .NET constructor injection of object created by other dependecy


Following problem:

I'm developing a WCF Service that uses RabbitMQ to connect to an API. We use spring as a DI container.

We made a consumer class (some custom logic for rabbit MQ + logging)

Trimmed down version:


public class Consumer : DefaultBasicConsumer
{
    public Consumer(IModel channel)
            : base(channel)
        {}
}

And we have a ConnectionManager class:


public class ConnectionManager
{
    public IModel Channel { get; set; }
    public IConnection Connection { get; set; }

    private readonly ConnectionFactory _connectionFactory;

    public ConnectionManager()
    {
        _connectionFactory = SetupConnectionFactory();

        Connection = _connectionFactory.CreateConnection();
        Channel = Connection.CreateModel();
    }
}

Now the problem, when wiring up everyting with Spring.NET. We want to inject the Channel property of the ConnectionManager class into the Consumer constructor.

Spring config so far (Trimmed down):

 <spring>
    <context>
      <resource uri="config://spring/objects"/>
    </context>
    <object name="connectionManager" type="Epex.ConnectionManager, EpexData" singleton="true"/>

    <object name="consumer" type="Epex.Consumer, EpexData">
      <constructor-arg ref="Do something funky here"/>
    </object>
</spring>

So what do I place on the Do Something funky here?

We could also rewrite and inject the ConnectionManager in the consumer (Last option)


Solution

  • You can modify ConnectionManager

    public class ConnectionManager
    {
      public IModel Channel { get; set; }
      public IConnection Connection { get; set; }
    
      private readonly ConnectionFactory _connectionFactory;
    
      public ConnectionManager()
      {
        _connectionFactory = SetupConnectionFactory();
    
        Connection = _connectionFactory.CreateConnection();
        Channel = Connection.CreateModel();
      }
    
      public IModel GetChannel()
      {
        return Channel;
      }
    }
    
     <spring>
        <context>
          <resource uri="config://spring/objects"/>
        </context>
        <object name="connectionManager" type="Epex.ConnectionManager, EpexData" singleton="true"/>
    
        <object name="consumer" type="Epex.Consumer, EpexData">
          <constructor-arg>
            <object factory-object="connectionManager" factory-method="GetChannel" />
          </constructor-arg>
        </object>
    </spring>