Search code examples
c#oopinversion-of-control

IoC and abstract classes


I'm writing a service that provides sentiment analysis of comments made by the public in various scenarios. For this I created the following interface:

Project A:

public interface ISentimentEngine
{
    SentimentEngineServices SentimentEngineProvider {get;}
    ISentimentEngineResult AnalyseSentiment(ISentimentRequest request);
}

I also have an abstract class which will contain some common functionality for my concrete implementations of the actual services:

Project B:

public abstract class SentimentEngineBase
{
    protected abstract int MaximumRequests { get; }
    protected SentimentEngineBase(string configurationXml)
    {

    }
    protected abstract SentimentEngineServices SentimentEngineProvider { get; }
    protected abstract string SentimentEngineName { get; }

    protected abstract void ProcessClientConfiguration(string configuration);
    protected abstract void GetDefaultConfiguration();
}

The above abstract class is in the same project as other objects, such as the response and request implementations and the interfaces are all in a separate contracts project (A), in an implementation of the stairway pattern.

Then the individual implementations are in further projects:

Project C:

public class MicrosoftAzureTextAnalyticsSentiment : SentimentEngineBase, ISentimentEngine
{

The thing I don't like is that the concrete implementation of the service will need to depend on the base abstract class (Project B), as well as the interface (Project A), as will all the implementations I create for each service provider, i.e. Microsoft Azure Text Analytics, Google Cloud Natural Language, Amazon Comprehend etc. which will all be in separate projected.

I want to use IoC and inject interfaces into the various objects constructors:

Options are:

  1. This is all good, it doesn't matter, don't worry about it and move on!!!
  2. Separate the base class into another project, Project D. Decoupling it from the other classes.
  3. Use interfaces only, moving some of the abstract methods to the interface; (but I really don't like them having public properties and having to do the leg work again all the time).
  4. Is there a different approach.

Sorry this is probably basic stuff to you guys and I'm probably missing something obvious but I can't see the wood for the trees.

Thanks,

Stu.


Solution

  • I think this is okay. Yes, project C which implements the interface will depend on projects A and B, as will project C' for Google Cloud Natural Language or C" for Amazon Comprehend. But a different project E with this SentimentEngineConsumer

    class SentimentEngineConsumer
    {
        ISentimentEngine _engine;
        public SentimentEngineConsumer(ISentimentEngine engine)
        {
            _engine = engine;
        }
    
        ...
    
    }
    

    only wants to use the interface will have no need for projects B, C, C', C", ... It can just use project A. It can be left to a dependency injection module to then link either C, C' or C" to project E.