Search code examples
dependency-injectionlaw-of-demeter

DI and Composite Components - Design


I'm designing a new component to a system, trying to follow the various guidelines on DI so we get payback in terms of isolation, mocking etc.

So I have the following components (illustrated as an abstraction):

  • Fetcher - supports IFetcher, which fetches data from a particular data source. Returns IDataSource.
  • Builder - supports IBuilder, which builds a structure from IDataSource.

I would like to wrap these up in a 'Performer' (for want of a better name) component, which would do the following:

IDataSet Performer.Perform(IFetcher fetcher, IBuilder builder)
{
  IDataSource ds = fetcher.Fetch();
  return builder.BuildDataSet(ds);
}

In order to comply with Dependency Injection and LoD guidelines (as far as I understand them anyway), I pass both the IFetcher and IBuilder components in.

My question - does this sound like an acceptable design? Conversations with work colleagues are along the lines of "yeah, sounds good" but not 100% convinced of the encapsulation by the Performer class.

The way I see it, the Performer is a composite-control which glues a couple of disparate components together, which should be acceptable. The only question mark is whether I should have a 'Performer Factory' but this seems overkill given that the actual components (IFetcher and IBuilder) can be mocked.

Any thoughts would be appreciated, thanks.


Solution

  • From a DI point of view, the only thing I would change is getting the fetcher and the builder in performer constructor. i.e.

    public class Performer { 
    
        private IFetcher fetcher; 
        private IBuilder builder;        
    
        public Performer(IFetcher fetcher, IBuilder builder) {
           this.fetcher = fetcher;
           this.builder = builder;
        }
    
        public IDataSet Perform(DataSource ds){
           IDataSource ds = fetcher.Fetch();
           return builder.BuildDataSet(ds); 
        }
    }
    

    And use a DI framework. No, I don´t think you need a factory method. Just call an IPerformer whenever you need one and the DI framework will build it for you.